fix(diff): preserve diff side for review comment locations - #1519
chaojixinren wants to merge 1 commit into
Conversation
Deleted-line matches already produced correct old-file coordinates, but the review model discarded whether those coordinates belonged to the old or new side. Carry the side through resolution and the machine-readable and GitHub review outputs so consumers can anchor findings without guessing. Constraint: Existing JSON without a side field must retain RIGHT-side behavior Constraint: Deleted-side SARIF regions cannot safely describe current-file replacements Rejected: Map deleted matches to a nearby RIGHT line | loses the exact deleted-code coordinate Confidence: high Scope-risk: moderate Reversibility: clean Directive: Consumers that parse review comments independently must preserve the optional side field Tested: make check; make test; targeted Go E2E; GitHub post-review-comments tests; git diff --check Not-tested: Viewer and IDE extension side propagation, which will be handled in a follow-up commit Related: alibaba#1486 Preserve diff side across review consumers The core review result now records whether a coordinate belongs to the old or new diff side, but the viewer and editor integrations used separate parsers and anchor models that discarded this metadata. Carry LEFT and RIGHT through session loading, viewer rendering, VS Code, and IDEA so deleted-line findings stay on the old snapshot and cannot be applied to the current workspace. Constraint: Legacy results without side metadata must retain existing status-based anchoring Constraint: A deleted-side coordinate has no safe location in the current workspace file Rejected: Let each editor infer the side from line validity or snippet lookup | can select RIGHT when the same line number exists on both snapshots Confidence: high Scope-risk: moderate Reversibility: clean Directive: Any new review-comment DTO or parser must preserve side and treat missing side as legacy RIGHT behavior Tested: make test; internal/viewer tests; VS Code Jest (96 tests); VS Code lint; git diff --check Not-tested: IDEA Gradle tests because this environment has no Java runtime Related: alibaba#1486 Keep diff-side handling consistent across extension UIs Review findings can target either side of a diff, so all extension surfaces must preserve that meaning in labels, actions, and anchor selection. Localize the old-side label and apply warning, simplify side-to-ref selection, and centralize IDEA side literals. Constraint: Existing LEFT/RIGHT JSON values and legacy missing-side behavior must remain compatible. Rejected: Reuse the stale-location warning for LEFT comments | an old-side coordinate cannot become valid by refreshing the current workspace. Confidence: high Scope-risk: narrow Directive: Keep old-side comments non-actionable in workspace mode and use the shared side constants for future IDEA comparisons. Tested: VS Code Jest 96 tests; VS Code lint; VS Code TypeScript compile; frontend typecheck and 17 tests; license check; English check; git diff --check. Not-tested: IDEA Gradle tests require a Java runtime; full Go test run is blocked by sandboxed local-port listeners in unrelated tests. Related: alibaba#1486
Design RationaleA schema-compatible alternative was considered in PR #1518: when a comment matches deleted code, it resets That approach prevents comments from being attached to unrelated new-file lines, but it also makes deleted-code findings unanchored. They can only appear in the summary and lose the precise location in the old file. This PR intentionally carries an explicit |
|
🔍 OpenCodeReview found 2 issue(s) in this PR.
📄
|
|
@NanaseInori review |
NanaseInori
left a comment
There was a problem hiding this comment.
I reviewed the current head (8a944f0). The core resolver change makes sense, and the GitHub / Viewer / VS Code / IDEA / SARIF propagation is generally coherent. I do see one cross-integration blocker, though.
The new side field is necessary precisely because a positive start_line / end_line is no longer sufficient to tell consumers which file version the coordinate belongs to. However, several first-party publishing integrations still ignore side and continue treating every positive line as a new/current-side coordinate.
For example, examples/gitlab_ci/post_review.py still turns every positive end_line into:
"new_line": end_line
without checking comment["side"].
A LEFT finding therefore sends an old-file line number as a GitLab new_line, recreating the same class of misattachment that #1486 is fixing for GitHub.
examples/gitflic_ci/post_review.py has the same assumption even more explicitly: its current documentation/comment says that ocr review only reports new-side positions, and the publisher uses end_line as newLine before deriving oldLine from it. That assumption becomes false once this PR starts emitting old-side coordinates.
examples/gerrit_ci/post_review.py likewise uses end_line directly as the current patch-set line without considering side.
I think these consumers need to be updated together with the output-schema change. Where a target platform supports an old-side coordinate, LEFT should be mapped correctly. Where it does not, the safe behavior is to fold the finding into the summary/non-inline path instead of posting an old-file line as a current-file line. Any incremental/deduplication logic that compares locations should also account for the side where applicable.
Please add LEFT regression coverage for the affected integration scripts as well.
There is also a GitHub multi-line edge case that I think should be pinned before considering the side model complete.
resolveFromHunk constructs the old side from context + deleted lines. Therefore an existing_code span such as:
keepBefore()
-legacyCall()
keepAfter()can resolve across a context line and a deleted line. The current model stores one Side for the whole resolved range, and the GitHub publisher then copies it to both start_side and side.
That means a mixed context/deletion range is represented as start_side=LEFT, side=LEFT even though the two endpoints do not necessarily have the same diff-side semantics. The current GitHub regression constructs a synthetic LEFT range directly, so it does not exercise this case from a real resolver result.
Please add a resolver-to-publisher regression for a multi-line old-side match containing context + deleted lines and either preserve the endpoint sides needed to represent it correctly, normalize the range to a safely representable deleted-side location, or degrade it rather than assuming one Side always describes both endpoints.
A documentation follow-up is also needed: this PR changes a public JSON field but only updates the English docs, and both open-code-review/SKILL.md copies still describe comment locations only in terms of start_line / end_line.
Other than these location-propagation issues, the core implementation looks solid to me. All current CI, CodeQL, IDEA, VS Code, frontend, Pages, translation-sync, and contract checks are green.
Requesting changes for the remaining side-unaware publishers and the mixed-side multi-line location case.
Description
Fixes #1486.
When
existing_codematches deleted code, the resolver already finds the correct old-file line number. However,LlmCommentdid not preserve whether the coordinate belonged to the old or new side of the diff. Downstream consumers therefore interpreted an old-file line as a new-file line and could attach the comment to unrelated code.This change adds an optional
sidefield to review comments:RIGHTidentifies coordinates in the new file.LEFTidentifies coordinates in the old file.sideretain the legacy RIGHT-side behavior.The side metadata is carried through:
Deleted-side SARIF findings retain their location metadata but do not emit replacements, because a deleted region cannot safely describe a replacement in the current file. In Workspace mode, LEFT-side comments remain viewable but cannot be applied to the current file.
The follow-up changes also localize the LEFT label and old-side apply warning, remove nested ternaries from the VS Code anchor resolver, and centralize IDEA side constants.
Type of Change
How Has This Been Tested?
make testpasses locally with-race -count=1git diff --checkpassedIDEA Gradle tests were not run because the local environment does not have a Java runtime.
Checklist
go fmt,go vet)AI Assistance Disclosure
This PR was implemented with OpenAI Codex (GPT-6) in Codex Desktop. I reviewed the generated code, tests, and documentation and understand the implementation.
Related Issues
Fixes #1486