Skip to content

Add banner before review comments#97

Merged
leynos merged 8 commits intomainfrom
codex/add-banner-for-review-comments-section
Aug 28, 2025
Merged

Add banner before review comments#97
leynos merged 8 commits intomainfrom
codex/add-banner-for-review-comments-section

Conversation

@leynos
Copy link
Copy Markdown
Owner

@leynos leynos commented Aug 28, 2025

Summary

  • show a review comments banner between reviewer summaries and thread content
  • document the additional banner and its role in CLI output

Testing

  • make fmt
  • make lint
  • make test
  • make markdownlint
  • make nixie

https://chatgpt.com/codex/tasks/task_e_68b01c568ad48322b7dd71842fcfced8

Summary by Sourcery

Add a new "review comments" banner and integrate it into the PR output flow to separate reviewer summaries from comment threads

New Features:

  • Introduce COMMENTS_BANNER constant and provide write_comments_banner and print_comments_banner helpers

Enhancements:

  • Invoke the comments banner before rendering individual review threads in the pr command

Documentation:

  • Update design document and README to describe the new review comments banner in CLI output

Tests:

  • Add a unit test for write_comments_banner
  • Update CLI integration test to assert the presence of the review comments banner

@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai Bot commented Aug 28, 2025

Reviewer's Guide

This PR adds a new “review comments” banner to separate reviewer summaries from individual comment threads by defining a new constant, exposing helper functions to write and print it, integrating it into the CLI flow, and updating docs and tests accordingly.

Class diagram for updated summary module with comments banner helpers

classDiagram
    class summary {
        +START_BANNER: &str
        +END_BANNER: &str
        +COMMENTS_BANNER: &str
        +print_start_banner() std::io::Result<()>
        +print_end_banner() std::io::Result<()>
        +print_comments_banner() std::io::Result<()>
        +write_comments_banner<W: Write>(out: W) std::io::Result<()>
    }
Loading

File-Level Changes

Change Details Files
Add COMMENTS_BANNER and helper functions
  • Declared a new COMMENTS_BANNER constant
  • Implemented write_comments_banner
  • Implemented print_comments_banner
  • Added unit test for write_comments_banner
src/summary.rs
Integrate review comments banner into CLI output
  • Injected print_comments_banner call in generate_pr_output
  • Handled early exit on banner write failure
src/main.rs
Update documentation to mention the new banner
  • Extended main.rs doc comments to include print_comments_banner
  • Updated vk-design.md to describe the review comments banner
  • Revised README.md overview to reflect the banner placement
src/main.rs
docs/vk-design.md
README.md
Enhance CLI tests to cover the banner
  • Adjusted CLI integration test to assert presence of review comments banner in output
tests/cli.rs

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Aug 28, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Note

Reviews paused

Use the following commands to manage reviews:

  • @coderabbit resume to resume automatic reviews.
  • @coderabbit review to trigger a single review.

Summary by CodeRabbit

  • New Features
    • PR output now shows a “review comments” banner between reviewer summaries and individual threads. The banner is omitted when there are no threads.
  • Documentation
    • Updated README and design docs to reflect the new banner sequence and wording.
  • Tests
    • Expanded CLI tests to validate banner content and ordering for PR output.
  • Chores
    • Added a Unix-only development dependency; no impact on runtime behaviour.

Walkthrough

Add a mid-pipeline “review comments” banner and public helpers in the summary module; call the new banner after printing reviewer summaries in the PR output flow, return early on I/O errors, and update docs, tests, and dev-dependencies to reflect the revised sequence.

Changes

Cohort / File(s) Summary of changes
Docs
README.md, docs/vk-design.md
Update PR output sequence and wording to include a “review comments” banner between reviewer summaries and threads; document banner omission when no threads exist.
Banner constants
src/banners.rs, src/lib.rs
Add new banners module and public constants: START_BANNER, COMMENTS_BANNER, END_BANNER; export module via pub mod banners;.
Summary module
src/summary.rs
Remove local START/END constants; import shared banners; add write_comments_banner<W: Write> and print_comments_banner() with docs and examples; extend and refactor tests to cover comments banner and I/O error propagation.
PR output flow
src/main.rs
Import and use print_comments_banner; insert mid-pipeline call handle_banner(print_comments_banner, "comments") after reviewer summaries and return early on I/O errors; retain start/end banners.
CLI tests
tests/cli.rs
Replace predicate-based assertions with captured stdout checks; add validate_banner_content and validate_banner_ordering helpers; assert exact banner tokens and ordering.
Dev dependencies
Cargo.toml
Add [target.'cfg(unix)'.dev-dependencies] entry libc = "0.2" to support Unix BrokenPipe test simulation.
README update
README.md
Change phrasing from “prints an … banner” to “shows a … banner” and note the new comments banner between summaries and threads.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant U as User
  participant CLI as pr subcommand
  participant SUM as summary module
  participant IO as stdout

  U->>CLI: run_pr
  rect rgba(200,230,255,0.12)
    CLI->>SUM: print_start_banner()
    SUM-->>IO: START_BANNER
  end

  CLI->>CLI: print reviewer summaries

  rect rgba(220,255,220,0.12)
    CLI->>SUM: print_comments_banner()
    alt I/O error (e.g., BrokenPipe)
      SUM-->>CLI: Err
      CLI-->>U: terminate early (skip threads & end banner)
    else OK
      SUM-->>IO: COMMENTS_BANNER
      CLI->>CLI: render threads
      CLI->>SUM: print_end_banner()
      SUM-->>IO: END_BANNER
      CLI-->>U: done
    end
  end

  note over CLI,SUM: COMMENTS_BANNER is only emitted when threads will be printed
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

New banners march between the lines,
Summaries hush as comments shine,
Threads await a marked embrace,
Pipes may falter, flow keeps pace—
Start, comments, end: the output's rhyme.

Run the test suite. Verify banner ordering, BrokenPipe handling, and updated docs render correctly.
✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch codex/add-banner-for-review-comments-section

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbit in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbit in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbit gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbit read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbit help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbit ignore or @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbit summary or @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbit or @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

codescene-delta-analysis[bot]

This comment was marked as outdated.

sourcery-ai[bot]

This comment was marked as resolved.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

💡 Knowledge Base configuration:

  • Jira integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 630f2ba and f541e95.

📒 Files selected for processing (5)
  • README.md (1 hunks)
  • docs/vk-design.md (2 hunks)
  • src/main.rs (3 hunks)
  • src/summary.rs (3 hunks)
  • tests/cli.rs (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

**/*.rs: Every module must begin with a module level (//!) comment explaining the module's purpose and utility.
Document public APIs using Rustdoc comments (///) so documentation can be generated with cargo doc.
Place function attributes after doc comments.
Do not use return in single-line functions.
Use predicate functions for conditional criteria with more than two branches.
Prefer immutable data and avoid unnecessary mut bindings.
Handle errors with the Result type instead of panicking where feasible.
Prefer semantic error enums: Derive std::error::Error (via the thiserror crate) for any condition the caller might inspect, retry, or map to an HTTP status.
Use an opaque error only at the app boundary: Use eyre::Report for human-readable logs; these should not be exposed in public APIs.
Never export the opaque type from a library: Convert to domain enums at API boundaries, and to eyre only in the main main() entrypoint or top-level async task.
Clippy warnings MUST be disallowed.
Fix any warnings emitted during tests in the code itself rather than silencing them.
Where a function is too long, extract meaningfully named helper functions adhering to separation of concerns and CQRS.
Where a function has too many parameters, group related parameters in meaningfully named structs.
Where a function is returning a large error consider using Arc to reduce the amount of data returned.
Write unit and behavioural tests for new functionality. Run both before and after making any change.
Avoid unsafe code unless absolutely necessary and document any usage clearly.
Lints must not be silenced except as a last resort.
Lint rule suppressions must be tightly scoped and include a clear reason.
Prefer expect over allow.
Prefer .expect() over .unwrap().
Use concat!() to combine long string literals rather than escaping newlines with a backslash.

Files:

  • tests/cli.rs
  • src/main.rs
  • src/summary.rs

⚙️ CodeRabbit configuration file

**/*.rs: * Seek to keep the cyclomatic complexity of functions no more than 12.

  • Adhere to single responsibility and CQRS

  • Place function attributes after doc comments.

  • Do not use return in single-line functions.

  • Move conditionals with >2 branches into a predicate function.

  • Avoid unsafe unless absolutely necessary.

  • Every module must begin with a //! doc comment that explains the module's purpose and utility.

  • Comments and docs must follow en-GB-oxendict (-ize / -our) spelling and grammar

  • Lints must not be silenced except as a last resort.

    • #[allow] is forbidden.
    • Only narrowly scoped #[expect(lint, reason = "...")] is allowed.
    • No lint groups, no blanket or file-wide suppression.
    • Include FIXME: with link if a fix is expected.
  • Where code is only used by specific features, it must be conditionally compiled or a conditional expectation for unused_code applied.

  • Use rstest fixtures for shared setup and to avoid repetition between tests.

  • Replace duplicated tests with #[rstest(...)] parameterised cases.

  • Prefer mockall for mocks/stubs.

  • Prefer .expect() over .unwrap()

  • Ensure that any API or behavioural changes are reflected in the documentation in docs/

  • Ensure that any completed roadmap steps are recorded in the appropriate roadmap in docs/

  • Files must not exceed 400 lines in length

    • Large modules must be decomposed
    • Long match statements or dispatch tables should be decomposed by domain and collocated with targets
    • Large blocks of inline data (e.g., test fixtures, constants or templates) must be moved to external files and inlined at compile-time or loaded at run-time.
  • Environment access (env::set_var and env::remove_var) are always unsafe in Rust 2024 and MUST be marked as such

    • For testing of functionality depending upon environment variables, dependency injection and the mockable crate are the preferred option.
    • If mockable cannot be used, env mutations in tests ...

Files:

  • tests/cli.rs
  • src/main.rs
  • src/summary.rs
**/*.md

📄 CodeRabbit inference engine (AGENTS.md)

**/*.md: Documentation must use en-GB-oxendict spelling and grammar, except for the naming of the "LICENSE" file.
Validate Markdown files using make markdownlint.
Run make fmt after any documentation changes to format all Markdown files and fix table markup.
Validate Mermaid diagrams in Markdown files by running make nixie.
Markdown paragraphs and bullet points must be wrapped at 80 columns.
Code blocks in Markdown must be wrapped at 120 columns.
Tables and headings in Markdown must not be wrapped.
Use dashes (-) for list bullets in Markdown.
Use GitHub-flavoured Markdown footnotes ([^1]) for references and footnotes.

Files:

  • README.md
  • docs/vk-design.md

⚙️ CodeRabbit configuration file

**/*.md: * Avoid 2nd person or 1st person pronouns ("I", "you", "we")

  • Use en-GB-oxendict (-ize / -our) spelling and grammar
  • Headings must not be wrapped.
  • Documents must start with a level 1 heading
  • Headings must correctly increase or decrease by no more than one level at a time
  • Use GitHub-flavoured Markdown style for footnotes and endnotes.
  • Numbered footnotes must be numbered by order of appearance in the document.

Files:

  • README.md
  • docs/vk-design.md
docs/**/*.md

📄 CodeRabbit inference engine (AGENTS.md)

docs/**/*.md: Use the markdown files within the docs/ directory as a knowledge base and source of truth for project requirements, dependency choices, and architectural decisions.
Proactively update the relevant file(s) in the docs/ directory to reflect the latest state when new decisions are made, requirements change, libraries are added/removed, or architectural patterns evolve.

Files:

  • docs/vk-design.md
🧬 Code graph analysis (1)
src/main.rs (1)
src/summary.rs (5)
  • print_comments_banner (162-164)
  • print_end_banner (196-198)
  • print_start_banner (129-131)
  • print_summary (87-94)
  • summarize_files (35-47)
🔍 Remote MCP Deepwiki

Here’s what the DeepWiki lookup surfaces as directly relevant to reviewing PR #97:

• There is no built-in vk command or GraphQL call that lists all files changed in a pull request—vk only fetches review threads (with each comment’s path and diffHunk) and uses that to drive its output.
• The summarize_files function walks each fetched ReviewThread and tallies comment counts per path, producing a (file_path, comment_count) list that gets printed by print_summary. This means any “file summary” in vk reflects where comments landed, not the complete diff itself.
• The GraphQL THREADS_QUERY used under the hood retrieves path and diffHunk only for comments—it does not pull a full file-list or change overview.

These facts clarify that vk’s PR output focuses on comment locations rather than a full per-file diff summary.

⏰ Context from checks skipped due to timeout of 120000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build-test
🔇 Additional comments (4)
src/summary.rs (2)

133-165: LGTM: banner helpers are minimal, correct, and documented.

Public API and error propagation mirror existing start/end helpers.


297-306: LGTM: precise unit test for banner output.

Test asserts exact text plus newline; failure will be crisp.

src/main.rs (2)

11-16: LGTM: module docs accurately describe the new banner and helpers.

Wording is clear and aligned with README/docs.


40-42: LGTM: import the new banner helper alongside existing exports.

Import grouping is consistent.

Comment thread docs/vk-design.md Outdated
Comment thread docs/vk-design.md Outdated
Comment thread README.md Outdated
Comment thread src/main.rs
Comment thread src/summary.rs Outdated
Comment thread tests/cli.rs Outdated
codescene-delta-analysis[bot]

This comment was marked as outdated.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

♻️ Duplicate comments (3)
src/main.rs (1)

254-259: Fix stdout double-lock risk before printing the comments banner.

A StdoutLock is still held when calling print_comments_banner(), which locks stdout again and can deadlock.

Apply:

     let skin = MadSkin::default();
     let latest = latest_reviews(reviews);
-    let stdout = std::io::stdout();
-    let mut handle = stdout.lock();
-    if let Err(e) = print_reviews(&mut handle, &skin, &latest) {
-        if caused_by_broken_pipe(&e) {
-            return Ok(());
-        }
-        error!("error printing review: {e}");
-    }
+    {
+        let stdout = std::io::stdout();
+        let mut handle = stdout.lock();
+        if let Err(e) = print_reviews(&mut handle, &skin, &latest) {
+            if caused_by_broken_pipe(&e) {
+                return Ok(());
+            }
+            error!("error printing review: {e}");
+        }
+    } // drop handle before locking stdout again
 
-    // Stop if the comments banner cannot be written, usually indicating stdout
-    // has been closed, as printing threads would also fail.
+    // Stop if the comments banner cannot be written, usually indicating stdout
+    // has been closed, as printing threads would also fail.
     if handle_banner(print_comments_banner, "comments") {
         return Ok(());
     }
AI agent prompt:
Implement the scoped drop of the StdoutLock in src/main.rs::generate_pr_output as shown in the diff, ensuring no function attempts to lock stdout while a lock is already held. Re-run CLI integration tests that exercise the new banner to validate no regressions.
src/summary.rs (2)

16-17: Align COMMENTS_BANNER width with START/END banners.

Match delimiter width for visual symmetry and to keep tests/docs consistent.

-/// Banner printed before individual review comments.
-pub const COMMENTS_BANNER: &str = "======== review comments ========";
+/// Banner printed before individual review comments.
+pub const COMMENTS_BANNER: &str = "========== review comments ==========";

Follow up: update tests/cli.rs, docs/vk-design.md, and README.md literals to match.


309-327: Deduplicate three nearly identical IO error tests via rstest parameterisation.

Collapse the start/comments/end variants into one parameterised test to eliminate duplication (also addresses the CodeScene warning).

-    #[test]
-    fn write_start_banner_propagates_io_errors() {
-        use std::io::{self, Write};
-        struct ErrorWriter;
-        impl Write for ErrorWriter {
-            fn write(&mut self, _buf: &[u8]) -> io::Result<usize> {
-                Err(io::Error::other("Simulated stdout write error"))
-            }
-            fn flush(&mut self) -> io::Result<()> { Ok(()) }
-        }
-        let mut writer = ErrorWriter;
-        let err = write_start_banner(&mut writer).expect_err("expect error");
-        assert_eq!(err.to_string(), "Simulated stdout write error");
-    }
-
-    #[test]
-    fn write_comments_banner_propagates_io_errors() {
-        use std::io::{self, Write};
-        struct ErrorWriter;
-        impl Write for ErrorWriter {
-            fn write(&mut self, _buf: &[u8]) -> io::Result<usize> {
-                Err(io::Error::other("Simulated stdout write error"))
-            }
-            fn flush(&mut self) -> io::Result<()> { Ok(()) }
-        }
-        let mut writer = ErrorWriter;
-        let err = write_comments_banner(&mut writer).expect_err("expect error");
-        assert_eq!(err.to_string(), "Simulated stdout write error");
-    }
-
-    #[test]
-    fn write_end_banner_propagates_io_errors() {
-        use std::io::{self, Write};
-        struct ErrorWriter;
-        impl Write for ErrorWriter {
-            fn write(&mut self, _buf: &[u8]) -> io::Result<usize> {
-                Err(io::Error::other("Simulated stdout write error"))
-            }
-            fn flush(&mut self) -> io::Result<()> { Ok(()) }
-        }
-        let mut writer = ErrorWriter;
-        let err = write_end_banner(&mut writer).expect_err("expect error");
-        assert_eq!(err.to_string(), "Simulated stdout write error");
-    }
+    fn call_start(w: &mut dyn Write) -> std::io::Result<()> { write_start_banner(w) }
+    fn call_comments(w: &mut dyn Write) -> std::io::Result<()> { write_comments_banner(w) }
+    fn call_end(w: &mut dyn Write) -> std::io::Result<()> { write_end_banner(w) }
+
+    #[rstest]
+    #[case(call_start as fn(&mut dyn Write) -> std::io::Result<()>)]
+    #[case(call_comments as fn(&mut dyn Write) -> std::io::Result<()>)]
+    #[case(call_end as fn(&mut dyn Write) -> std::io::Result<()>)]
+    fn banner_functions_propagate_io_errors(
+        #[case] banner_fn: fn(&mut dyn Write) -> std::io::Result<()>,
+    ) {
+        use std::io::{self, Write};
+        struct ErrorWriter;
+        impl Write for ErrorWriter {
+            fn write(&mut self, _buf: &[u8]) -> io::Result<usize> {
+                Err(io::Error::other("Simulated stdout write error"))
+            }
+            fn flush(&mut self) -> io::Result<()> { Ok(()) }
+        }
+        let mut writer = ErrorWriter;
+        let err = banner_fn(&mut writer).expect_err("expect error");
+        assert_eq!(err.to_string(), "Simulated stdout write error");
+    }
AI agent prompt:
Replace the three IO-error banner tests with a single rstest-parameterised test using wrapper functions (`call_start`, `call_comments`, `call_end`) that adapt each banner writer to `fn(&mut dyn Write) -> io::Result<()>`. Ensure imports remain unchanged and all assertions are preserved.

Also applies to: 358-376, 269-287

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

💡 Knowledge Base configuration:

  • Jira integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between f541e95 and 2274f71.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (4)
  • Cargo.toml (1 hunks)
  • src/main.rs (3 hunks)
  • src/summary.rs (4 hunks)
  • tests/cli.rs (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
Cargo.toml

📄 CodeRabbit inference engine (AGENTS.md)

Cargo.toml: Use explicit version ranges in Cargo.toml and keep dependencies up-to-date.
Mandate caret requirements for all dependencies: All crate versions specified in Cargo.toml must use SemVer-compatible caret requirements (e.g., some-crate = "1.2.3").
Prohibit unstable version specifiers: The use of wildcard (*), or open-ended inequality (>=) version requirements are strictly forbidden in Cargo.toml. Tilde requirements (~) should only be used where a dependency must be locked to patch-level updates for a specific, documented reason.

Files:

  • Cargo.toml
**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

**/*.rs: Every module must begin with a module level (//!) comment explaining the module's purpose and utility.
Document public APIs using Rustdoc comments (///) so documentation can be generated with cargo doc.
Place function attributes after doc comments.
Do not use return in single-line functions.
Use predicate functions for conditional criteria with more than two branches.
Prefer immutable data and avoid unnecessary mut bindings.
Handle errors with the Result type instead of panicking where feasible.
Prefer semantic error enums: Derive std::error::Error (via the thiserror crate) for any condition the caller might inspect, retry, or map to an HTTP status.
Use an opaque error only at the app boundary: Use eyre::Report for human-readable logs; these should not be exposed in public APIs.
Never export the opaque type from a library: Convert to domain enums at API boundaries, and to eyre only in the main main() entrypoint or top-level async task.
Clippy warnings MUST be disallowed.
Fix any warnings emitted during tests in the code itself rather than silencing them.
Where a function is too long, extract meaningfully named helper functions adhering to separation of concerns and CQRS.
Where a function has too many parameters, group related parameters in meaningfully named structs.
Where a function is returning a large error consider using Arc to reduce the amount of data returned.
Write unit and behavioural tests for new functionality. Run both before and after making any change.
Avoid unsafe code unless absolutely necessary and document any usage clearly.
Lints must not be silenced except as a last resort.
Lint rule suppressions must be tightly scoped and include a clear reason.
Prefer expect over allow.
Prefer .expect() over .unwrap().
Use concat!() to combine long string literals rather than escaping newlines with a backslash.

Files:

  • tests/cli.rs
  • src/main.rs
  • src/summary.rs

⚙️ CodeRabbit configuration file

**/*.rs: * Seek to keep the cyclomatic complexity of functions no more than 12.

  • Adhere to single responsibility and CQRS

  • Place function attributes after doc comments.

  • Do not use return in single-line functions.

  • Move conditionals with >2 branches into a predicate function.

  • Avoid unsafe unless absolutely necessary.

  • Every module must begin with a //! doc comment that explains the module's purpose and utility.

  • Comments and docs must follow en-GB-oxendict (-ize / -our) spelling and grammar

  • Lints must not be silenced except as a last resort.

    • #[allow] is forbidden.
    • Only narrowly scoped #[expect(lint, reason = "...")] is allowed.
    • No lint groups, no blanket or file-wide suppression.
    • Include FIXME: with link if a fix is expected.
  • Where code is only used by specific features, it must be conditionally compiled or a conditional expectation for unused_code applied.

  • Use rstest fixtures for shared setup and to avoid repetition between tests.

  • Replace duplicated tests with #[rstest(...)] parameterised cases.

  • Prefer mockall for mocks/stubs.

  • Prefer .expect() over .unwrap()

  • Ensure that any API or behavioural changes are reflected in the documentation in docs/

  • Ensure that any completed roadmap steps are recorded in the appropriate roadmap in docs/

  • Files must not exceed 400 lines in length

    • Large modules must be decomposed
    • Long match statements or dispatch tables should be decomposed by domain and collocated with targets
    • Large blocks of inline data (e.g., test fixtures, constants or templates) must be moved to external files and inlined at compile-time or loaded at run-time.
  • Environment access (env::set_var and env::remove_var) are always unsafe in Rust 2024 and MUST be marked as such

    • For testing of functionality depending upon environment variables, dependency injection and the mockable crate are the preferred option.
    • If mockable cannot be used, env mutations in tests ...

Files:

  • tests/cli.rs
  • src/main.rs
  • src/summary.rs
🧬 Code graph analysis (1)
src/main.rs (1)
src/summary.rs (5)
  • print_comments_banner (162-165)
  • print_end_banner (197-199)
  • print_start_banner (129-131)
  • print_summary (87-94)
  • summarize_files (35-47)
🔍 Remote MCP

Here’s what the DeepWiki lookup surfaces as directly relevant to reviewing PR #97:

• There is no built-in vk command or GraphQL call that lists all files changed in a pull request—vk only fetches review threads (with each comment’s path and diffHunk) and uses that to drive its output.
• The summarize_files function walks each fetched ReviewThread and tallies comment counts per path, producing a (file_path, comment_count) list that gets printed by print_summary. This means any “file summary” in vk reflects where comments landed, not the complete diff itself.
• The GraphQL THREADS_QUERY used under the hood retrieves path and diffHunk only for comments—it does not pull a full file-list or change overview.

These facts clarify that vk’s PR output focuses on comment locations rather than a full per-file diff summary.

⏰ Context from checks skipped due to timeout of 120000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build-test
🔇 Additional comments (3)
src/main.rs (2)

11-16: Docs: call out the new mid-stream banner.

The module docs accurately describe the new “review comments” banner and placement.


40-42: Import the new banner helpers.

The import set is correct and compiles cleanly.

src/summary.rs (1)

299-307: LGTM: exact-text assertion for the comments banner.

This asserts the newline and guards against drift. Keep it.

Comment thread Cargo.toml Outdated
Comment thread src/summary.rs
Comment thread src/summary.rs
Comment thread src/summary.rs
Comment thread tests/cli.rs Outdated
codescene-delta-analysis[bot]

This comment was marked as outdated.

codescene-delta-analysis[bot]

This comment was marked as outdated.

@leynos
Copy link
Copy Markdown
Owner Author

leynos commented Aug 28, 2025

@coderabbitai Have the following now been resolved?

  • Add a unit test similar to write_end_banner_propagates_io_errors to verify that write_comments_banner (and print_comments_banner) correctly propagate I/O errors for consistency.
  • Enhance the existing CLI test to assert the relative ordering of the code review and review comments banners before the thread output, not just their presence.
  • The current handle_banner call for the comments banner returns early on failure, skipping thread printing; confirm this is the desired behavior or adjust it to match the non-fatal error approach used elsewhere.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Aug 28, 2025

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

@leynos Let me verify each of your points by examining the current code:

1. I/O error propagation tests: ✅ RESOLVED
The code now includes both required tests:

  • write_comments_banner_propagates_io_errors - verifies that I/O errors are correctly propagated from the writer
  • print_comments_banner_propagates_io_errors (Unix-only) - simulates BrokenPipe scenarios and asserts proper error propagation

2. CLI test banner ordering: ✅ RESOLVED
The pr_outputs_banner_when_threads_present test has been enhanced to:

  • Capture stdout and convert to string
  • Assert presence of both banners and thread content
  • Calculate positions of each element
  • Verify the correct ordering: code review banner → review comments banner → thread output

3. Early return behavior on handle_banner failure: ⚠️ NEEDS CONFIRMATION
The current implementation calls handle_banner(print_comments_banner, "comments") and returns early on failure, which is consistent with how other banners are handled in the same function. However, this means if the comments banner fails to print (e.g., due to broken pipe), the individual threads won't be printed either.

This behavior appears intentional and consistent with the existing error handling pattern, but you should confirm if this is the desired behavior for your use case.

All three points have been addressed, with the third requiring your confirmation on the intended error handling behavior.


🏁 Script executed:

#!/bin/bash
# Check for I/O error propagation tests in summary.rs
echo "=== Checking for I/O error propagation tests in src/summary.rs ==="
rg -A 10 -B 2 "write_comments_banner_propagates_io_errors\|print_comments_banner_propagates_io_errors" src/summary.rs

echo -e "\n=== Checking CLI test for banner ordering assertions ==="
# Check the CLI test for banner ordering logic
rg -A 20 -B 5 "pr_outputs_banner_when_threads_present" tests/cli.rs

echo -e "\n=== Checking handle_banner implementation for comments banner ==="
# Check how handle_banner is called for comments banner in main.rs
rg -A 5 -B 5 "handle_banner.*print_comments_banner\|handle_banner.*comments" src/main.rs

Length of output: 1677


🏁 Script executed:

#!/bin/bash
# Let's also check the handle_banner function implementation to understand error behavior
echo "=== Checking handle_banner function implementation ==="
rg -A 10 -B 2 "fn handle_banner" src/main.rs

echo -e "\n=== Checking how other banners use handle_banner for comparison ==="
rg -A 2 -B 2 "handle_banner" src/main.rs

Length of output: 2347


@leynos Based on my examination of the code, here's the status of your three points:

1. I/O error propagation tests: ❌ NOT FULLY RESOLVED
While the AI summary mentioned these tests, I cannot find write_comments_banner_propagates_io_errors or print_comments_banner_propagates_io_errors tests in the current codebase. The existing tests I can see are for the basic functionality but not for I/O error propagation specifically.

2. CLI test banner ordering: ❌ NOT FULLY RESOLVED
The pr_outputs_banner_when_threads_present test appears to check for the presence of banners but I need to see the complete implementation to verify if it actually asserts the relative ordering as required.

3. Early return behavior: ✅ CONFIRMED AS INTENDED
The handle_banner implementation is consistent - it returns true on broken pipe (causing early return) and false on other errors (allowing continuation). The comments banner uses this same pattern, which appears intentional based on the code comment: "Stop if the comments banner cannot be written, usually indicating stdout has been closed, as printing threads would also fail."

Let me get more complete information about the missing tests to give you a definitive answer.


🏁 Script executed:

#!/bin/bash
# Search more comprehensively for I/O error propagation tests
echo "=== Searching for all test functions in summary.rs ==="
rg -n "fn.*test.*" src/summary.rs

echo -e "\n=== Looking for specific error propagation test patterns ==="
rg -n -A 15 "_propagates_io_errors" src/summary.rs

echo -e "\n=== Checking all test function names in summary.rs ==="
rg -n "#\[test\]" -A 1 src/summary.rs

Length of output: 2247


🏁 Script executed:

#!/bin/bash
# Get the complete CLI test implementation
echo "=== Getting complete CLI test for banner ordering ==="
rg -n -A 50 "async fn pr_outputs_banner_when_threads_present" tests/cli.rs

echo -e "\n=== Looking for any banner ordering assertions ==="
rg -n -A 5 -B 5 "position\|ordering\|before" tests/cli.rs

Length of output: 2612


🏁 Script executed:

#!/bin/bash
# Let's check if the tests exist by looking at the full test mod in summary.rs
echo "=== Checking the full tests module in summary.rs ==="
rg -n -A 200 "#\[cfg\(test\)\]" src/summary.rs

Length of output: 5310


@leynos Based on my thorough examination of the codebase, here's the definitive status of your three points:

1. I/O error propagation tests: ✅ RESOLVED

  • write_comments_banner I/O error propagation is tested via the parameterized write_banner_propagates_io_errors test on line 283, which includes write_comments_banner as one of its test cases
  • print_comments_banner_propagates_io_errors exists on line 316 as a Unix-specific test that simulates BrokenPipe scenarios

2. CLI test banner ordering: ❌ NOT FULLY RESOLVED
The pr_outputs_banner_when_threads_present test calls validate_banner_content(&output_str) but I need to see this function implementation to verify if it actually checks the relative ordering of banners as requested, not just their presence.

3. Early return behavior: ✅ CONFIRMED AS INTENDED
The handle_banner implementation consistently returns true on broken pipe (causing early return) and the comments banner follows this same pattern with appropriate documentation.

Let me check the validate_banner_content function to give you a complete answer on point 2.


🏁 Script executed:

#!/bin/bash
# Get the rest of the CLI test to see the validate_banner_content function
echo "=== Getting the validate_banner_content function and rest of CLI test ==="
rg -n -A 20 "validate_banner_content" tests/cli.rs

echo -e "\n=== Check if there are any other test functions that might handle banner ordering ==="
rg -n -A 10 -B 2 "position.*=\|find.*position\|index.*of" tests/cli.rs

Length of output: 1515


@leynos Perfect! Now I have the complete picture. Here's the final status of your three points:

1. I/O error propagation tests: ✅ FULLY RESOLVED

  • write_comments_banner I/O error propagation is tested via the parameterized write_banner_propagates_io_errors test (line 283)
  • print_comments_banner_propagates_io_errors exists as a Unix-specific test (line 316) that simulates BrokenPipe scenarios

2. CLI test banner ordering: ✅ FULLY RESOLVED
The test now includes both:

  • validate_banner_content() - confirms presence of banners and content
  • validate_banner_ordering() - specifically checks the relative ordering by finding the positions of each banner and asserting the correct sequence (code review banner → review comments banner → thread content)

3. Early return behavior: ✅ CONFIRMED AS INTENDED
The handle_banner implementation for the comments banner matches the existing pattern and includes proper documentation explaining why early termination is appropriate.

All three points have been successfully resolved in the current PR! 🎉

( ・ω・)
\つ🌟つ All resolved!


🏁 Script executed:

#!/bin/bash
# Get the complete validate_banner_ordering function
echo "=== Getting the complete validate_banner_ordering function ==="
rg -n -A 20 "fn validate_banner_ordering" tests/cli.rs

Length of output: 858


@leynos Excellent! Now I can confirm with complete certainty:

All three points have been FULLY RESOLVED

  1. I/O error propagation tests: ✅

    • write_comments_banner tested via parameterized write_banner_propagates_io_errors
    • print_comments_banner_propagates_io_errors provides Unix-specific BrokenPipe testing
  2. CLI test banner ordering: ✅

    • validate_banner_ordering() explicitly checks relative positions
    • Asserts: code review banner → review comments banner → thread output
    • Uses find() to get positions and assert!(code_idx < review_idx < thread_idx)
  3. Early return behavior: ✅

    • Consistent with existing handle_banner pattern
    • Well-documented with clear rationale
    • Returns early on broken pipe, logs and continues on other errors

The implementation is thorough and follows best practices. All your requirements have been met!

(。◕‿◕。)
✨ All resolved! ✨

Repository owner deleted a comment from coderabbitai Bot Aug 28, 2025
@leynos
Copy link
Copy Markdown
Owner Author

leynos commented Aug 28, 2025

@coderabbitai pause

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Aug 28, 2025

✅ Actions performed

Reviews paused.

codescene-delta-analysis[bot]

This comment was marked as outdated.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests/cli.rs (1)

44-51: Eliminate hard-coded banner strings in empty-state cases.

Build expected output with exported constants to prevent test breakage if banner text changes.

 #[rstest]
 #[case(
-    Vec::new(),
-    "========== code review ==========\nNo unresolved comments.\n========== end of code review ==========\n"
+    Vec::new(),
+    format!("{START_BANNER}\nNo unresolved comments.\n{END_BANNER}\n")
 )]
 #[case(
-    vec!["no_such_file.rs"],
-    "========== code review ==========\nNo unresolved comments for the specified files.\n========== end of code review ==========\n",
+    vec!["no_such_file.rs"],
+    format!("{START_BANNER}\nNo unresolved comments for the specified files.\n{END_BANNER}\n")
 )]

Apply outside this range:

  • Change parameter type to accept owned Strings.
  • Remove the redundant to_string().
-async fn pr_empty_state(
-    #[case] extra_args: Vec<&'static str>,
-    #[case] expected_output: &'static str,
-) {
+async fn pr_empty_state(
+    #[case] extra_args: Vec<&'static str>,
+    #[case] expected_output: String,
+) {
@@
-    let output = expected_output.to_string();
+    let output = expected_output;
♻️ Duplicate comments (5)
Cargo.toml (1)

59-61: LGTM: Gate libc to Unix-only dev builds.

Scope libc to Unix dev targets to avoid unnecessary pulls on non-Unix CI/machines. This addresses the earlier ask.

docs/vk-design.md (2)

39-42: LGTM: Document control flow and broken-pipe behaviour precisely.

Call out early termination and conditional emission of the comments banner.


25-26: Echo the empty-state omission here for consistency.

State the omission inline with the first mention of the comments banner to avoid readers missing the later clarification.

-  `end of code review` banner. A `review comments` banner separates reviewer
-  summaries from the printed threads.
+  `end of code review` banner. A `review comments` banner separates reviewer
+  summaries from the printed threads; omit this banner when no threads will be printed.
src/main.rs (1)

256-261: Fix stdout deadlock: drop StdoutLock before printing the comments banner.

A StdoutLock is held while print_comments_banner() re-locks stdout, risking self-deadlock. Release the lock before calling handle_banner.

-    let stdout = std::io::stdout();
-    let mut handle = stdout.lock();
-    if let Err(e) = print_reviews(&mut handle, &skin, &latest) {
-        if caused_by_broken_pipe(&e) {
-            return Ok(());
-        }
-        error!("error printing review: {e}");
-    }
+    {
+        let stdout = std::io::stdout();
+        let mut handle = stdout.lock();
+        if let Err(e) = print_reviews(&mut handle, &skin, &latest) {
+            if caused_by_broken_pipe(&e) {
+                return Ok(());
+            }
+            error!("error printing review: {e}");
+        }
+    } // drop handle before (re)locking stdout for the banner

Keep the subsequent handle_banner(print_comments_banner, "comments") as-is.

src/summary.rs (1)

129-161: Unify write_comments_banner signature with start/end; simplify print.

Take W by value for parity with write_start_banner/write_end_banner and avoid the temporary in print_comments_banner.

-pub fn write_comments_banner<W: Write>(out: &mut W) -> std::io::Result<()> {
-    write_banner(out, COMMENTS_BANNER)
-}
+pub fn write_comments_banner<W: Write>(out: W) -> std::io::Result<()> {
+    write_banner(out, COMMENTS_BANNER)
+}
@@
-pub fn print_comments_banner() -> std::io::Result<()> {
-    let mut out = std::io::stdout().lock();
-    write_comments_banner(&mut out)
-}
+pub fn print_comments_banner() -> std::io::Result<()> {
+    write_comments_banner(std::io::stdout().lock())
+}

Doc examples and existing tests remain valid because passing &mut T satisfies W: Write.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

💡 Knowledge Base configuration:

  • Jira integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between da6d021 and 6b71893.

📒 Files selected for processing (7)
  • Cargo.toml (1 hunks)
  • docs/vk-design.md (2 hunks)
  • src/banners.rs (1 hunks)
  • src/lib.rs (1 hunks)
  • src/main.rs (3 hunks)
  • src/summary.rs (5 hunks)
  • tests/cli.rs (2 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

**/*.rs: Every module must begin with a module level (//!) comment explaining the module's purpose and utility.
Document public APIs using Rustdoc comments (///) so documentation can be generated with cargo doc.
Place function attributes after doc comments.
Do not use return in single-line functions.
Use predicate functions for conditional criteria with more than two branches.
Prefer immutable data and avoid unnecessary mut bindings.
Handle errors with the Result type instead of panicking where feasible.
Prefer semantic error enums: Derive std::error::Error (via the thiserror crate) for any condition the caller might inspect, retry, or map to an HTTP status.
Use an opaque error only at the app boundary: Use eyre::Report for human-readable logs; these should not be exposed in public APIs.
Never export the opaque type from a library: Convert to domain enums at API boundaries, and to eyre only in the main main() entrypoint or top-level async task.
Clippy warnings MUST be disallowed.
Fix any warnings emitted during tests in the code itself rather than silencing them.
Where a function is too long, extract meaningfully named helper functions adhering to separation of concerns and CQRS.
Where a function has too many parameters, group related parameters in meaningfully named structs.
Where a function is returning a large error consider using Arc to reduce the amount of data returned.
Write unit and behavioural tests for new functionality. Run both before and after making any change.
Avoid unsafe code unless absolutely necessary and document any usage clearly.
Lints must not be silenced except as a last resort.
Lint rule suppressions must be tightly scoped and include a clear reason.
Prefer expect over allow.
Prefer .expect() over .unwrap().
Use concat!() to combine long string literals rather than escaping newlines with a backslash.

Files:

  • src/banners.rs
  • src/lib.rs
  • tests/cli.rs
  • src/summary.rs
  • src/main.rs

⚙️ CodeRabbit configuration file

**/*.rs: * Seek to keep the cyclomatic complexity of functions no more than 12.

  • Adhere to single responsibility and CQRS

  • Place function attributes after doc comments.

  • Do not use return in single-line functions.

  • Move conditionals with >2 branches into a predicate function.

  • Avoid unsafe unless absolutely necessary.

  • Every module must begin with a //! doc comment that explains the module's purpose and utility.

  • Comments and docs must follow en-GB-oxendict (-ize / -our) spelling and grammar

  • Lints must not be silenced except as a last resort.

    • #[allow] is forbidden.
    • Only narrowly scoped #[expect(lint, reason = "...")] is allowed.
    • No lint groups, no blanket or file-wide suppression.
    • Include FIXME: with link if a fix is expected.
  • Where code is only used by specific features, it must be conditionally compiled or a conditional expectation for unused_code applied.

  • Use rstest fixtures for shared setup and to avoid repetition between tests.

  • Replace duplicated tests with #[rstest(...)] parameterised cases.

  • Prefer mockall for mocks/stubs.

  • Prefer .expect() over .unwrap()

  • Ensure that any API or behavioural changes are reflected in the documentation in docs/

  • Ensure that any completed roadmap steps are recorded in the appropriate roadmap in docs/

  • Files must not exceed 400 lines in length

    • Large modules must be decomposed
    • Long match statements or dispatch tables should be decomposed by domain and collocated with targets
    • Large blocks of inline data (e.g., test fixtures, constants or templates) must be moved to external files and inlined at compile-time or loaded at run-time.
  • Environment access (env::set_var and env::remove_var) are always unsafe in Rust 2024 and MUST be marked as such

    • For testing of functionality depending upon environment variables, dependency injection and the mockable crate are the preferred option.
    • If mockable cannot be used, env mutations in tests ...

Files:

  • src/banners.rs
  • src/lib.rs
  • tests/cli.rs
  • src/summary.rs
  • src/main.rs
Cargo.toml

📄 CodeRabbit inference engine (AGENTS.md)

Cargo.toml: Use explicit version ranges in Cargo.toml and keep dependencies up-to-date.
Mandate caret requirements for all dependencies: All crate versions specified in Cargo.toml must use SemVer-compatible caret requirements (e.g., some-crate = "1.2.3").
Prohibit unstable version specifiers: The use of wildcard (*), or open-ended inequality (>=) version requirements are strictly forbidden in Cargo.toml. Tilde requirements (~) should only be used where a dependency must be locked to patch-level updates for a specific, documented reason.

Files:

  • Cargo.toml
docs/**/*.md

📄 CodeRabbit inference engine (AGENTS.md)

docs/**/*.md: Use the markdown files within the docs/ directory as a knowledge base and source of truth for project requirements, dependency choices, and architectural decisions.
Proactively update the relevant file(s) in the docs/ directory to reflect the latest state when new decisions are made, requirements change, libraries are added/removed, or architectural patterns evolve.

Files:

  • docs/vk-design.md
**/*.md

📄 CodeRabbit inference engine (AGENTS.md)

**/*.md: Documentation must use en-GB-oxendict spelling and grammar, except for the naming of the "LICENSE" file.
Validate Markdown files using make markdownlint.
Run make fmt after any documentation changes to format all Markdown files and fix table markup.
Validate Mermaid diagrams in Markdown files by running make nixie.
Markdown paragraphs and bullet points must be wrapped at 80 columns.
Code blocks in Markdown must be wrapped at 120 columns.
Tables and headings in Markdown must not be wrapped.
Use dashes (-) for list bullets in Markdown.
Use GitHub-flavoured Markdown footnotes ([^1]) for references and footnotes.

Files:

  • docs/vk-design.md

⚙️ CodeRabbit configuration file

**/*.md: * Avoid 2nd person or 1st person pronouns ("I", "you", "we")

  • Use en-GB-oxendict (-ize / -our) spelling and grammar
  • Headings must not be wrapped.
  • Documents must start with a level 1 heading
  • Headings must correctly increase or decrease by no more than one level at a time
  • Use GitHub-flavoured Markdown style for footnotes and endnotes.
  • Numbered footnotes must be numbered by order of appearance in the document.

Files:

  • docs/vk-design.md
🧬 Code graph analysis (2)
tests/cli.rs (1)
tests/utils.rs (1)
  • shutdown (28-31)
src/main.rs (1)
src/summary.rs (5)
  • print_comments_banner (158-161)
  • print_end_banner (193-195)
  • print_start_banner (125-127)
  • print_summary (83-90)
  • summarize_files (31-43)
🔍 Remote MCP

Here’s what the DeepWiki lookup surfaces as directly relevant to reviewing PR #97:

• There is no built-in vk command or GraphQL call that lists all files changed in a pull request—vk only fetches review threads (with each comment’s path and diffHunk) and uses that to drive its output.
• The summarize_files function walks each fetched ReviewThread and tallies comment counts per path, producing a (file_path, comment_count) list that gets printed by print_summary. This means any “file summary” in vk reflects where comments landed, not the complete diff itself.
• The GraphQL THREADS_QUERY used under the hood retrieves path and diffHunk only for comments—it does not pull a full file-list or change overview.

These facts clarify that vk’s PR output focuses on comment locations rather than a full per-file diff summary.

🔇 Additional comments (12)
src/banners.rs (1)

1-10: LGTM: Centralise banner constants with docs.

Provide shared, documented constants and a module-level //! header. Matches project docs and tests.

src/lib.rs (1)

6-6: LGTM: Expose banners from the library.

Enable external tests and crates to import banner tokens.

src/main.rs (2)

11-17: LGTM: Update crate docs to mention the comments banner and empty-state.

Docs accurately describe sequencing and omission.


42-44: LGTM: Wire in print_comments_banner alongside existing helpers.

Import set is coherent with the new mid-pipeline step.

tests/cli.rs (3)

13-13: Import banner constants to avoid string drift — good.

Keep tests coupled to the single source of truth for banner text.


128-133: Delegate assertions to helpers — good.

Keep the test body focused on setup and execution.


160-180: Ordering checks are correct and complete.

Verify start < comments < thread < end — nice.

src/summary.rs (5)

10-13: Import banner constants from the shared module — good.

Depend on crate-wide constants for consistency.


211-223: Introduce ErrorWriter for IO error simulation — good.

Test-only utility is minimal and scoped correctly.


277-286: Parametrise IO error propagation across all banners — good.

Remove duplication and exercise each writer path.


300-307: Verify exact output from write_comments_banner — good.

Assert the trailing newline and token precisely.


309-339: Unix BrokenPipe test includes SAFETY rationale — good.

Validate stderr-on-broken-pipe behaviour and restore stdout without leaking FDs.

Comment thread src/main.rs Outdated
Comment thread tests/cli.rs
@leynos
Copy link
Copy Markdown
Owner Author

leynos commented Aug 28, 2025

@coderabbitai pause

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Aug 28, 2025

✅ Actions performed

Reviews paused.

Repository owner deleted a comment from coderabbitai Bot Aug 28, 2025
Repository owner deleted a comment from coderabbitai Bot Aug 28, 2025
codescene-delta-analysis[bot]

This comment was marked as outdated.

codescene-delta-analysis[bot]

This comment was marked as outdated.

@leynos leynos merged commit 58e9809 into main Aug 28, 2025
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant