feat: inline review comments on specific lines #26

Merged
rodin merged 6 commits from feat/inline-review-comments into main 2026-05-02 06:13:02 +00:00
Owner

Findings that reference a file+line within the diff are now posted as inline comments directly on that line. Findings outside the diff range stay in the body only.

Changes

  • gitea/diff.go: Parse unified diff to extract new-file line numbers per hunk
  • gitea/client.go: PostReview accepts optional []ReviewComment
  • cmd/review-bot/main.go: Maps findings → inline comments when line is in diff

Tests

  • Diff parser: multi-hunk, new files, empty diff, boundary lines
  • PostReview: with comments, nil comments (omitted from payload)

Closes #26

Findings that reference a file+line within the diff are now posted as inline comments directly on that line. Findings outside the diff range stay in the body only. ## Changes - `gitea/diff.go`: Parse unified diff to extract new-file line numbers per hunk - `gitea/client.go`: `PostReview` accepts optional `[]ReviewComment` - `cmd/review-bot/main.go`: Maps findings → inline comments when line is in diff ## Tests - Diff parser: multi-hunk, new files, empty diff, boundary lines - PostReview: with comments, nil comments (omitted from payload) Closes #26
rodin added 1 commit 2026-05-02 04:59:29 +00:00
feat: inline review comments on specific lines
CI / test (pull_request) Successful in 13s
CI / review (gpt-4.1, gpt, GPT_REVIEW_TOKEN) (pull_request) Successful in 23s
CI / review (gpt-5, security, SECURITY_REVIEW.md, SONNET_REVIEW_TOKEN) (pull_request) Successful in 43s
CI / review (gpt-5, sonnet, SONNET_REVIEW_TOKEN) (pull_request) Successful in 1m29s
2ac7f55396
Findings that reference a file+line within the diff are now posted as
inline comments directly on that line, in addition to appearing in the
summary table. Findings outside the diff range stay in the body only.

Implementation:
- gitea/diff.go: ParseDiffNewLines extracts new-file line numbers from
  each hunk in the unified diff
- gitea/client.go: PostReview accepts optional []ReviewComment with
  path + new_position + body (omitempty when nil)
- cmd/review-bot/main.go: maps findings → inline comments when the line
  exists in the diff, passes them to PostReview

Tests:
- diff parser: multi-hunk, new files, empty diff, boundary lines
- PostReview: with comments, nil comments (omitted from payload)
rodin added 1 commit 2026-05-02 05:10:52 +00:00
fix: handle single-line hunks and no-newline markers in diff parser
CI / test (pull_request) Successful in 14s
CI / review (gpt-4.1, gpt, GPT_REVIEW_TOKEN) (pull_request) Successful in 23s
CI / review (gpt-5, security, SECURITY_REVIEW.md, SONNET_REVIEW_TOKEN) (pull_request) Successful in 55s
CI / review (gpt-5, sonnet, SONNET_REVIEW_TOKEN) (pull_request) Successful in 1m42s
b0dc6d0c09
- Hunk headers without comma ("@@ -1 +1 @@") now parse correctly by
  splitting on comma OR space instead of comma only
- Explicit skip for "\ No newline at end of file" lines (was already
  safe but now documents intent)
- Tests added for both edge cases (TDD: tests written first, confirmed
  failure, then fixed)

Addresses sonnet findings #1 and #2 from PR #26 review.
rodin added 1 commit 2026-05-02 05:17:39 +00:00
feat: skip re-posting when review is unchanged (preserve threads)
CI / test (pull_request) Successful in 14s
CI / review (gpt-4.1, gpt, GPT_REVIEW_TOKEN) (pull_request) Successful in 23s
CI / review (gpt-5, security, SECURITY_REVIEW.md, SONNET_REVIEW_TOKEN) (pull_request) Successful in 1m1s
CI / review (gpt-5, sonnet, SONNET_REVIEW_TOKEN) (pull_request) Successful in 1m28s
1c2292265b
Before posting, compare the new review body+event against the existing
review with the same sentinel. If identical, skip entirely — this
preserves conversation threads on inline comments and avoids
re-notifying reviewers for findings they already know about.

Only re-posts when findings actually change (fixed, new, or different).

Tests: 6 cases covering identical, different body, different state,
stale reviews, and different sentinels.
gpt-review-bot approved these changes 2026-05-02 05:18:17 +00:00
gpt-review-bot left a comment
First-time contributor

Gpt Review

Summary

The changes add support for mapping findings to inline comments on changed lines in the diff, refactoring review update logic, and extending test coverage for new behaviors. Implementation is idiomatic, test-backed, and aligns with repo conventions.

Recommendation

APPROVE — The PR is well-structured and incorporates a robust solution for associating findings with inline comments, including utility for diff range mapping and a conservative in-place review update strategy. The changes are covered with comprehensive tests and maintain clean separation of concerns. No issues found—ready to merge.


Review by gpt

# Gpt Review ## Summary The changes add support for mapping findings to inline comments on changed lines in the diff, refactoring review update logic, and extending test coverage for new behaviors. Implementation is idiomatic, test-backed, and aligns with repo conventions. ## Recommendation **APPROVE** — The PR is well-structured and incorporates a robust solution for associating findings with inline comments, including utility for diff range mapping and a conservative in-place review update strategy. The changes are covered with comprehensive tests and maintain clean separation of concerns. No issues found—ready to merge. --- *Review by gpt* <!-- review-bot:gpt -->
sonnet-review-bot approved these changes 2026-05-02 05:18:55 +00:00
sonnet-review-bot left a comment
First-time contributor

Security Review

Summary

The changes add inline review comments mapped to diff lines and introduce safe, well-structured Gitea client methods for posting comments and editing review bodies. CI passed and the code follows good error handling and path safety practices, with only minor hardening opportunities identified.

Findings

# Severity File Line Finding
1 [MINOR] gitea/client.go 138 PostReview constructs the request URL using raw owner and repo values without path-escaping (fmt.Sprintf(".../repos/%s/%s/...", owner, repo)). If these inputs ever contain characters like '/' or '..', it could lead to path injection or incorrect endpoints. Other methods (e.g., ListReviews) use url.PathEscape for these components; apply the same here.
2 [NIT] cmd/review-bot/main.go 241 Inline comment bodies include unescaped LLM-generated content (f.Finding). While Gitea typically sanitizes Markdown/HTML, relying solely on downstream sanitization can risk XSS if settings change. Consider minimally sanitizing or constraining the content format before posting.

Recommendation

APPROVE — Overall, the implementation is sound and security-conscious (notably the workspace-bound file reads and consistent error wrapping). To further harden:

  • In gitea/client.go PostReview, escape owner and repo with url.PathEscape to align with other methods and prevent path injection edge cases.
  • Consider sanitizing or restricting the format of inline comment bodies prior to submission, or explicitly document the reliance on Gitea's Markdown sanitization.
    With these minor adjustments, the feature should be secure in typical deployments.

Review by security

# Security Review ## Summary The changes add inline review comments mapped to diff lines and introduce safe, well-structured Gitea client methods for posting comments and editing review bodies. CI passed and the code follows good error handling and path safety practices, with only minor hardening opportunities identified. ## Findings | # | Severity | File | Line | Finding | |---|----------|------|------|--------| | 1 | [MINOR] | `gitea/client.go` | 138 | PostReview constructs the request URL using raw owner and repo values without path-escaping (fmt.Sprintf(".../repos/%s/%s/...", owner, repo)). If these inputs ever contain characters like '/' or '..', it could lead to path injection or incorrect endpoints. Other methods (e.g., ListReviews) use url.PathEscape for these components; apply the same here. | | 2 | [NIT] | `cmd/review-bot/main.go` | 241 | Inline comment bodies include unescaped LLM-generated content (f.Finding). While Gitea typically sanitizes Markdown/HTML, relying solely on downstream sanitization can risk XSS if settings change. Consider minimally sanitizing or constraining the content format before posting. | ## Recommendation **APPROVE** — Overall, the implementation is sound and security-conscious (notably the workspace-bound file reads and consistent error wrapping). To further harden: - In gitea/client.go PostReview, escape owner and repo with url.PathEscape to align with other methods and prevent path injection edge cases. - Consider sanitizing or restricting the format of inline comment bodies prior to submission, or explicitly document the reliance on Gitea's Markdown sanitization. With these minor adjustments, the feature should be secure in typical deployments. --- *Review by security* <!-- review-bot:security -->
sonnet-review-bot approved these changes 2026-05-02 05:19:22 +00:00
sonnet-review-bot left a comment
First-time contributor

Sonnet Review

Summary

Well-scoped feature addition enabling inline review comments with a solid diff parser and comprehensive tests. API changes are propagated correctly and review update strategy is improved to preserve threads.

Findings

# Severity File Line Finding
1 [MINOR] gitea/client.go 62 ReviewComment uses JSON field name "new_position"; verify this matches Gitea's API for creating review comments. Some APIs expect "position" or "line" instead, and a mismatch could silently drop inline comments.
2 [MINOR] cmd/review-bot/main.go 244 Inline comment mapping uses new-file line numbers as NewPosition. Ensure this aligns with the server’s expectation (diff position vs. file line number) to avoid misplaced or rejected inline comments.
3 [NIT] gitea/diff.go 18 Diff parser extracts new-file line ranges from unified diffs; consider documenting assumptions (e.g., only "+++ b/" headers are used to set current file) and any limitations (renames, binary diffs), though tests cover common cases.
4 [NIT] cmd/review-bot/main.go 311 When marking a previous review as superseded, EditComment errors are logged but not acted upon. If superseding is critical to your workflow, consider surfacing or retrying these failures.

Recommendation

APPROVE — The implementation cleanly introduces inline review comments by parsing unified diffs and extending the Gitea client to submit comments alongside reviews. Tests cover the diff parser (multi-hunk, new files, edge markers) and the new client behavior (comments omitempty, EditComment, timeline lookup). The refactored review update strategy (edit-in-place, supersede on state change, worst-wins escalation without deletion) is thoughtful and documented in the new REVIEW_STRATEGY.md. One point to double-check is the payload schema for inline comments: "new_position" may not match what Gitea expects; confirm against the Gitea API (whether it requires "position" or "line" semantics, and whether values are diff positions vs. file line numbers). Aside from that, the changes are solid and CI has passed. I recommend approval.


Review by sonnet

# Sonnet Review ## Summary Well-scoped feature addition enabling inline review comments with a solid diff parser and comprehensive tests. API changes are propagated correctly and review update strategy is improved to preserve threads. ## Findings | # | Severity | File | Line | Finding | |---|----------|------|------|--------| | 1 | [MINOR] | `gitea/client.go` | 62 | ReviewComment uses JSON field name "new_position"; verify this matches Gitea's API for creating review comments. Some APIs expect "position" or "line" instead, and a mismatch could silently drop inline comments. | | 2 | [MINOR] | `cmd/review-bot/main.go` | 244 | Inline comment mapping uses new-file line numbers as NewPosition. Ensure this aligns with the server’s expectation (diff position vs. file line number) to avoid misplaced or rejected inline comments. | | 3 | [NIT] | `gitea/diff.go` | 18 | Diff parser extracts new-file line ranges from unified diffs; consider documenting assumptions (e.g., only "+++ b/" headers are used to set current file) and any limitations (renames, binary diffs), though tests cover common cases. | | 4 | [NIT] | `cmd/review-bot/main.go` | 311 | When marking a previous review as superseded, EditComment errors are logged but not acted upon. If superseding is critical to your workflow, consider surfacing or retrying these failures. | ## Recommendation **APPROVE** — The implementation cleanly introduces inline review comments by parsing unified diffs and extending the Gitea client to submit comments alongside reviews. Tests cover the diff parser (multi-hunk, new files, edge markers) and the new client behavior (comments omitempty, EditComment, timeline lookup). The refactored review update strategy (edit-in-place, supersede on state change, worst-wins escalation without deletion) is thoughtful and documented in the new REVIEW_STRATEGY.md. One point to double-check is the payload schema for inline comments: "new_position" may not match what Gitea expects; confirm against the Gitea API (whether it requires "position" or "line" semantics, and whether values are diff positions vs. file line numbers). Aside from that, the changes are solid and CI has passed. I recommend approval. --- *Review by sonnet* <!-- review-bot:sonnet -->
@@ -452,0 +482,4 @@
for _, r := range reviews {
if r.Stale {
continue
}
First-time contributor

[MINOR] old finding Superseded by newer review

~~**[MINOR]** old finding~~ *Superseded by newer review*
@@ -0,0 +43,4 @@
currentFile = ""
continue
}
First-time contributor

[NIT] Hunk header parsing uses strings.Split(line, "+") and then trims at comma/space. While adequate for typical diffs, consider a more targeted parse (e.g., locating the first '+' between the '@@' markers) to be more robust against unusual hunk headers.

**[NIT]** Hunk header parsing uses `strings.Split(line, "+")` and then trims at comma/space. While adequate for typical diffs, consider a more targeted parse (e.g., locating the first '+' between the '@@' markers) to be more robust against unusual hunk headers.
rodin added 1 commit 2026-05-02 05:46:46 +00:00
feat: edit-in-place review updates (no more delete)
CI / test (pull_request) Successful in 13s
CI / review (gpt-4.1, gpt, GPT_REVIEW_TOKEN) (pull_request) Successful in 23s
CI / review (gpt-5, sonnet, SONNET_REVIEW_TOKEN) (pull_request) Successful in 1m37s
CI / review (gpt-5, security, SECURITY_REVIEW.md, SONNET_REVIEW_TOKEN) (pull_request) Successful in 1m43s
e261976dd8
Replace the delete-and-repost strategy with edit-in-place:

1. No existing review → POST new (first run)
2. Same state, same body → skip entirely (threads preserved)
3. Same state, body changed → PATCH body in place via timeline API
4. State change needed → PATCH old body to "Superseded", POST new

This preserves conversation threads on inline comments. Replies to
findings are never lost. The only time a new review is posted is on
first run or when the state transitions (APPROVED ↔ REQUEST_CHANGES).

New Gitea client methods:
- EditComment: PATCH /repos/{owner}/{repo}/issues/comments/{id}
- GetTimelineReviewCommentID: finds the comment ID for a review body
  by scanning the issue timeline for the sentinel

Also simplifies shouldEscalate: removes the login parameter requirement
for pre-posting scenarios (uses findOwnReview to get login from existing
review instead).

Tests: findOwnReview (4 cases), EditComment (2 cases),
GetTimelineReviewCommentID (2 cases), shouldEscalate (8 cases updated).
sonnet-review-bot requested changes 2026-05-02 05:48:38 +00:00
sonnet-review-bot left a comment
First-time contributor

Sonnet Review

Summary

Solid feature addition: parses unified diffs and posts inline comments with good test coverage. However, the review escalation logic was altered in a way that can incorrectly post APPROVED when a sibling bot review has REQUEST_CHANGES on the first run, which is a functional regression.

Findings

# Severity File Line Finding
1 [MAJOR] cmd/review-bot/main.go 268 Escalation now happens before posting and depends on deriving ownLogin from an existing review containing the sentinel. On the first run (no existing review with this sentinel), ownLogin is empty and escalation is skipped, so an APPROVED review may be posted even if a sibling bot (same token) already has REQUEST_CHANGES. Previously this was handled by escalating after posting using the posted user login.
2 [MINOR] gitea/client.go 388 EditComment marshals the payload with json.Marshal but ignores the error (data, _ := json.Marshal(payload)). This can mask unexpected failures; handle and return the marshal error similar to PostReview.
3 [NIT] cmd/review-bot/main.go 499 In reviewUnchanged, the condition existingEvent == r.State is redundant since existingEvent is assigned from r.State. Simplify to r.State == newEvent && r.Body == newBody.

Recommendation

REQUEST_CHANGES — Address the escalation logic regression to ensure the bot doesn't post APPROVED when a sibling review from the same user (same token) has REQUEST_CHANGES on a first run without a prior sentinel. Options:

  • Query the current user (the bot) via the Gitea API using the token to obtain ownLogin before deciding on escalation; then call shouldEscalate with that login.
  • Or retain a post-posting escalation fallback: after posting, if event == APPROVED, fetch reviews and re-check escalation using the posted review's user.login (as the previous implementation did), updating or superseding as needed.
    Additionally, in gitea/client.go’s EditComment, handle the json.Marshal error instead of ignoring it to comply with the repository’s error-handling conventions. Finally, clean up the redundant comparison in reviewUnchanged for clarity. With these changes, the inline comment feature and review update strategy will be robust and aligned with the intended behavior.

Review by sonnet

# Sonnet Review ## Summary Solid feature addition: parses unified diffs and posts inline comments with good test coverage. However, the review escalation logic was altered in a way that can incorrectly post APPROVED when a sibling bot review has REQUEST_CHANGES on the first run, which is a functional regression. ## Findings | # | Severity | File | Line | Finding | |---|----------|------|------|--------| | 1 | [MAJOR] | `cmd/review-bot/main.go` | 268 | Escalation now happens before posting and depends on deriving ownLogin from an existing review containing the sentinel. On the first run (no existing review with this sentinel), ownLogin is empty and escalation is skipped, so an APPROVED review may be posted even if a sibling bot (same token) already has REQUEST_CHANGES. Previously this was handled by escalating after posting using the posted user login. | | 2 | [MINOR] | `gitea/client.go` | 388 | EditComment marshals the payload with json.Marshal but ignores the error (data, _ := json.Marshal(payload)). This can mask unexpected failures; handle and return the marshal error similar to PostReview. | | 3 | [NIT] | `cmd/review-bot/main.go` | 499 | In reviewUnchanged, the condition `existingEvent == r.State` is redundant since existingEvent is assigned from r.State. Simplify to `r.State == newEvent && r.Body == newBody`. | ## Recommendation **REQUEST_CHANGES** — Address the escalation logic regression to ensure the bot doesn't post APPROVED when a sibling review from the same user (same token) has REQUEST_CHANGES on a first run without a prior sentinel. Options: - Query the current user (the bot) via the Gitea API using the token to obtain ownLogin before deciding on escalation; then call shouldEscalate with that login. - Or retain a post-posting escalation fallback: after posting, if event == APPROVED, fetch reviews and re-check escalation using the posted review's user.login (as the previous implementation did), updating or superseding as needed. Additionally, in gitea/client.go’s EditComment, handle the json.Marshal error instead of ignoring it to comply with the repository’s error-handling conventions. Finally, clean up the redundant comparison in reviewUnchanged for clarity. With these changes, the inline comment feature and review update strategy will be robust and aligned with the intended behavior. --- *Review by sonnet* <!-- review-bot:sonnet -->
@@ -254,3 +265,4 @@
existingReviews, err := giteaClient.ListReviews(ctx, owner, repoName, prNumber)
if err != nil {
log.Printf("Warning: could not list existing reviews: %v", err)
} else {
First-time contributor

[MAJOR] Escalation now happens before posting and depends on deriving ownLogin from an existing review containing the sentinel. On the first run (no existing review with this sentinel), ownLogin is empty and escalation is skipped, so an APPROVED review may be posted even if a sibling bot (same token) already has REQUEST_CHANGES. Previously this was handled by escalating after posting using the posted user login.

**[MAJOR]** Escalation now happens before posting and depends on deriving ownLogin from an existing review containing the sentinel. On the first run (no existing review with this sentinel), ownLogin is empty and escalation is skipped, so an APPROVED review may be posted even if a sibling bot (same token) already has REQUEST_CHANGES. Previously this was handled by escalating after posting using the posted user login.
@@ -449,3 +496,4 @@
}
return false
}
First-time contributor

[NIT] In reviewUnchanged, the condition existingEvent == r.State is redundant since existingEvent is assigned from r.State. Simplify to r.State == newEvent && r.Body == newBody.

**[NIT]** In reviewUnchanged, the condition `existingEvent == r.State` is redundant since existingEvent is assigned from r.State. Simplify to `r.State == newEvent && r.Body == newBody`.
@@ -346,0 +385,4 @@
return 0, fmt.Errorf("parse timeline (page %d): %w", page, err)
}
for _, ev := range events {
if ev.Type == "review" && strings.Contains(ev.Body, sentinel) {
First-time contributor

[MINOR] EditComment marshals the payload with json.Marshal but ignores the error (data, _ := json.Marshal(payload)). This can mask unexpected failures; handle and return the marshal error similar to PostReview.

**[MINOR]** EditComment marshals the payload with json.Marshal but ignores the error (data, _ := json.Marshal(payload)). This can mask unexpected failures; handle and return the marshal error similar to PostReview.
sonnet-review-bot requested changes 2026-05-02 05:48:44 +00:00
sonnet-review-bot left a comment
First-time contributor

Security Review

Summary

Security-focused changes look sound: inline comments are restricted to lines present in the diff, API requests use context and timeouts, and edit/escalation logic avoids destructive actions when not permitted. CI passed. I have a couple of minor hardening suggestions.

Findings

# Severity File Line Finding
1 [MINOR] gitea/client.go 140 PostReview constructs the reviews API URL using owner and repo without url.PathEscape, which can lead to malformed paths if these contain unexpected characters or slashes. While inputs are typically controlled, escaping path segments (as done elsewhere in this client) is a defense-in-depth improvement.
2 [MINOR] cmd/review-bot/main.go 477 shouldEscalate relies on detecting a 'sentinel' substring in review bodies to identify sibling bot reviews. An untrusted user could spoof the sentinel in their own review, potentially causing unintended escalation. Consider additionally verifying the matched review's user login matches the bot's account (derived independently from the API) before treating it as a sibling.

Recommendation

APPROVE — Overall, the implementation is secure and aligns with best practices: inline comments are only posted on lines verified from the parsed diff, all HTTP calls use a bounded http.Client with context, and update-in-place logic gracefully falls back on permission errors. To further harden the code: (1) use url.PathEscape for owner and repo in PostReview (and other endpoints that still use raw values) to prevent path mishandling; (2) tighten sibling review identification by cross-checking the bot's own login or another reliable identifier to prevent sentinel spoofing from influencing escalation decisions. With these minor adjustments, the changes should be robust.


Review by security

# Security Review ## Summary Security-focused changes look sound: inline comments are restricted to lines present in the diff, API requests use context and timeouts, and edit/escalation logic avoids destructive actions when not permitted. CI passed. I have a couple of minor hardening suggestions. ## Findings | # | Severity | File | Line | Finding | |---|----------|------|------|--------| | 1 | [MINOR] | `gitea/client.go` | 140 | PostReview constructs the reviews API URL using owner and repo without url.PathEscape, which can lead to malformed paths if these contain unexpected characters or slashes. While inputs are typically controlled, escaping path segments (as done elsewhere in this client) is a defense-in-depth improvement. | | 2 | [MINOR] | `cmd/review-bot/main.go` | 477 | shouldEscalate relies on detecting a 'sentinel' substring in review bodies to identify sibling bot reviews. An untrusted user could spoof the sentinel in their own review, potentially causing unintended escalation. Consider additionally verifying the matched review's user login matches the bot's account (derived independently from the API) before treating it as a sibling. | ## Recommendation **APPROVE** — Overall, the implementation is secure and aligns with best practices: inline comments are only posted on lines verified from the parsed diff, all HTTP calls use a bounded http.Client with context, and update-in-place logic gracefully falls back on permission errors. To further harden the code: (1) use url.PathEscape for owner and repo in PostReview (and other endpoints that still use raw values) to prevent path mishandling; (2) tighten sibling review identification by cross-checking the bot's own login or another reliable identifier to prevent sentinel spoofing from influencing escalation decisions. With these minor adjustments, the changes should be robust. --- *Review by security* <!-- review-bot:security -->
@@ -438,14 +477,52 @@ func validateReviewerName(name string) error {
return nil
First-time contributor

[MINOR] shouldEscalate relies on detecting a 'sentinel' substring in review bodies to identify sibling bot reviews. An untrusted user could spoof the sentinel in their own review, potentially causing unintended escalation. Consider additionally verifying the matched review's user login matches the bot's account (derived independently from the API) before treating it as a sibling.

**[MINOR]** shouldEscalate relies on detecting a 'sentinel' substring in review bodies to identify sibling bot reviews. An untrusted user could spoof the sentinel in their own review, potentially causing unintended escalation. Consider additionally verifying the matched review's user login matches the bot's account (derived independently from the API) before treating it as a sibling.
@@ -131,15 +138,18 @@ func (c *Client) GetFileContentRef(ctx context.Context, owner, repo, filepath, r
// PostReview submits a review to a PR and returns the created review.
// event should be "APPROVED" or "REQUEST_CHANGES".
First-time contributor

[MINOR] PostReview constructs the reviews API URL using owner and repo without url.PathEscape, which can lead to malformed paths if these contain unexpected characters or slashes. While inputs are typically controlled, escaping path segments (as done elsewhere in this client) is a defense-in-depth improvement.

**[MINOR]** PostReview constructs the reviews API URL using owner and repo without url.PathEscape, which can lead to malformed paths if these contain unexpected characters or slashes. While inputs are typically controlled, escaping path segments (as done elsewhere in this client) is a defense-in-depth improvement.
rodin added 1 commit 2026-05-02 05:50:15 +00:00
fix: address review findings (escalation, marshal error, redundant check)
CI / test (pull_request) Successful in 13s
CI / review (gpt-4.1, gpt, GPT_REVIEW_TOKEN) (pull_request) Successful in 23s
CI / review (gpt-5, security, SECURITY_REVIEW.md, SONNET_REVIEW_TOKEN) (pull_request) Successful in 1m11s
CI / review (gpt-5, sonnet, SONNET_REVIEW_TOKEN) (pull_request) Successful in 1m21s
ec19622133
1. First-run escalation regression (MAJOR): Add post-posting escalation
   fallback. After posting APPROVED on first run, check if a sibling
   from the same user has REQUEST_CHANGES — if so, mark ours as
   superseded and re-post as REQUEST_CHANGES.

2. json.Marshal error handling (MINOR): Return error from EditComment
   instead of ignoring it with blank identifier.

3. Redundant condition (NIT): Remove dead assignment in reviewUnchanged
   where existingEvent was assigned from r.State then compared to itself.
rodin added 1 commit 2026-05-02 06:01:34 +00:00
docs: add review update strategy with state transition diagram
CI / test (pull_request) Successful in 12s
CI / review (gpt-4.1, gpt, GPT_REVIEW_TOKEN) (pull_request) Successful in 24s
CI / review (gpt-5, sonnet, SONNET_REVIEW_TOKEN) (pull_request) Successful in 1m17s
CI / review (gpt-5, security, SECURITY_REVIEW.md, SONNET_REVIEW_TOKEN) (pull_request) Successful in 1m22s
a9c8ecfb0b
Explains the edit-in-place approach, state transition rules, worst-wins
escalation, and inline comment lifecycle. Includes a Mermaid state
diagram for visual reference.
aweiker approved these changes 2026-05-02 06:12:57 +00:00
aweiker left a comment
Contributor

Ship it.

Ship it.
rodin merged commit d80d6a23a2 into main 2026-05-02 06:13:02 +00:00
Sign in to join this conversation.
4 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: rodin/review-bot#26