trail finding: populate selected_text for line/range findings#1444
Open
Soph wants to merge 1 commit into
Open
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes entire trail finding add --line/--start-line being rejected by the control plane by ensuring selected_text is populated for line/range locations (via --selected-text or by auto-reading the anchored lines from the local worktree under safety gates). Also refactors git dirty/HEAD comparison utilities and updates unit tests to cover the new behavior.
Changes:
- Add
--selected-textand auto-readselected_textfor line/range finding locations (with branch/dirty-file/HEAD safety gating). - Refactor finding creation to finalize input after starting a review (to access the review head SHA) and reuse a shared local-HEAD comparator.
- Introduce
gitStatusDirty(ctx, root, pathspecs...)and update tests for the new selected-text and review-finalization flow.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| cmd/entire/cli/trail_review_cmd.go | Adds selected-text support + auto-read gate; refactors review/finding submission flow and HEAD comparison. |
| cmd/entire/cli/trail_review_cmd_test.go | Adds unit tests for selected-text behavior, auto-read gates, and updated create-finding flow. |
| cmd/entire/cli/git_operations.go | Adds reusable gitStatusDirty helper and updates HasUncommittedChanges to use it. |
a4dd3a6 to
7520d4a
Compare
`entire trail finding add --line/--start-line` always failed against the control plane with `location.granularity=line requires non-empty selected_text`: the CLI built a line/range location but never set `selected_text`, and there was no flag to supply it. Only `--file` (file-granularity, no selected_text requirement) worked. selected_text is the diff anchor, so it must be the source text at those lines. Two ways to provide it now: - `--selected-text` flag — explicit, always wins. - Auto-read from the local working tree when the flag is omitted, behind a safety gate so the anchor text provably matches the trail's reviewed code: the finding's branch must equal the checked-out branch, the target file must have no uncommitted changes, and the trail head SHA must equal local HEAD. The user-supplied --file is validated (no absolute paths, no `..` escape, no .git) and the file is read through os.Root, which confines the open to the repo root at the kernel level and rejects symlinks that escape it. Any gate failure (or out-of-range lines) is a hard error pointing at `--selected-text`. Lines are joined with "\n" and capped at 16384 chars, matching the server's own selectedTextFromPatch derivation. The branch and clean-file checks run before the review is started, so those misconfigurations fail without side effects. The trail head SHA is only returned by starting the review, so `createTrailReviewFinding` finalizes the input via a callback that runs after the review is opened, where the HEAD-match check happens — a HEAD mismatch there does leave an empty review session (rare: requires the right branch and a clean tree but a different commit than the trail tip). Also factor out two shared helpers while here: `compareLocalHead` (now used by both the new head check and the existing `verifyTrailReviewHead`) and `gitStatusDirty` (now backing `HasUncommittedChanges` and the file-scoped clean check). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 3e51051232cb
7520d4a to
7335c7d
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
https://entire.io/gh/entireio/cli/trails/580/trail-finding-populate-selected-text-for-line-range-findings
Problem
entire trail finding add --line/--start-linealways failed against the control plane with:The CLI built a
line/rangelocation but never setselected_text, and there was no flag to supply it (TrailReviewLocationCreateRequest.SelectedTextexisted but nothing ever assigned it). The server requires it for line/range granularity (validateLocationShapein the BFF). Only--file(which maps tofilegranularity, noselected_textrequirement) worked — so line-anchored findings were dead on arrival.Fix
selected_textis the diff anchor, so it must be the actual source text at those lines. Two ways to provide it:--selected-textflag — explicit, always wins.Auto-read from the local working tree when the flag is omitted, behind a safety gate so the anchor text provably matches the trail's reviewed code:
HEAD.The user-supplied
--fileis validated (no absolute paths, no..escape, no.git) via the existingvalidatePatchPathbefore any filesystem access. Any gate failure (or out-of-range lines) is a hard error pointing at--selected-text. Lines are joined with\nand capped at 16384 chars, matching the server's ownselectedTextFromPatchderivation.Gate ordering / empty-review caveat
The branch and clean-file checks run before the review is started, so those misconfigurations fail with no server side effects. The trail head SHA is only returned by
startTrailReview, socreateTrailReviewFindingfinalizes the input via a callback that runs after the review is opened — and that's where the HEAD-match check happens. A HEAD mismatch therefore leaves an empty review session behind. This is a rare edge (you'd be on the right branch with a clean tree but at a different commit than the trail tip); pre-checking it would need a way to fetch the trail head without opening a review, which the API doesn't currently expose. Flagged rather than re-architected.Refactors (no behavior change)
compareLocalHead— shared by the new head check and the existingverifyTrailReviewHead.gitStatusDirty(ctx, root, pathspecs...)— now backs bothHasUncommittedChanges(empty root → unchanged CWD behavior) and the new file-scoped clean check.Testing
locationNeedsSelectedText, and the gate (readSelectedTextFromWorktreehappy path + branch-mismatch + path-escape + out-of-range + dirty-file;verifyTrailHeadMatchesLocalnil/match/mismatch).mise run fmt && mise run lintclean; fullcmd/entire/clisuite green.rangefinding (lines 260–262 ofgit_operations.go) to this branch's trail via the auto-read path; the server accepted it and stored the correctselected_text— the exact case that previously failed.🤖 Generated with Claude Code