Repository navigation
Find an incremental baseline by commit ancestry when the branch has none - #178
Conversation
A detached CI checkout reports no branch, so the baseline lookup asked only about trunk and never found the pipeline's own earlier scans, which recorded no branch either. When the checkout names no branch, pick the recent scan whose commit is nearest behind HEAD (any branch, including none), then fall back to the trunk lookup. The git diff no longer requires a branch name, which it never used. Co-authored-by: ibrahim <ibrahim@corgea.com>
| } | ||
| if let Some(scan) = | ||
| nearest_ancestor_baseline(&scans, ancestry, checksums_usable, git_diffable) | ||
| { |
There was a problem hiding this comment.
nitpick: Ancestor search stops before finding the nearest baseline
The function returns as soon as any page contains an ancestor. Since pages are ordered by scan creation time rather than commit distance, a later page can contain a much nearer ancestor. This contradicts the stated nearest-baseline behavior and can unnecessarily rescan many files. Track the best candidate across all searched pages before returning.
Proof or reproduction:
Page 1: scan(root, 100 commits back) -> immediately returned
Page 2: scan(parent_of_head, 1 commit back) -> never examined
corgea-security
left a comment
There was a problem hiding this comment.
Automated review risk: 2/5.
The detached-HEAD baseline logic is sound overall, but pagination can select a substantially older baseline despite promising the nearest ancestor.
No critical or high-priority changes were found.
corgea-security
left a comment
There was a problem hiding this comment.
Approved by Dennis: high policy risk and automated risk 2/5.
Walk HEAD's nearest 50 commits locally (breadth-first over every parent) and ask the scan list for scans of any of them in one request, instead of paging the project's recent scans and testing each for ancestry. Matches are re-checked client-side for backends that ignore the list. Runs after the branch's own lookup and before trunk's, so the first scan of a branch whose trunk is not main or master diffs against the commit it forked from, and a detached HEAD finds its pipeline's earlier runs. Co-authored-by: ibrahim <ibrahim@corgea.com>
…e and detached trunk fallback The ancestor lookup decides whether a commit-only baseline is usable from the same function plan_git_diff refuses with, so a change to when a git diff is allowed cannot leave the two disagreeing. E2E: a failed lookup by commit scans everything and says the lookup failed, and a detached HEAD with no scanned recent commit reaches trunk. Co-authored-by: ibrahim <ibrahim@corgea.com>
A backend that cannot answer a list of commits, or errors on it, must not cost the trunk baseline earlier releases found. The failure is treated as no match and the trunk lookup runs; if the endpoint itself is down, that lookup fails and the run says so. The refusal only claims no recent commit was scanned when the lookup by commit actually answered. Co-authored-by: ibrahim <ibrahim@corgea.com>
Co-authored-by: ibrahim <ibrahim@corgea.com>


A small percentage of pipelines are checked out with detached head (no branch is resolved) so we aren't able to locate the same branch base so I'm adding a fallback to try to identify a base using the commit history instead.
LLM desc:
Problem
The CLI only finds a baseline by branch name: the scanned branch, then
origin/HEAD, thenmainormaster. Two common cases find nothing, even when a recent ancestor commit was scanned:mainormaster. For example, a project whose trunk isdevelop. The trunk lookup never asks aboutdevelop, so the branch scans everything. Production data shows this is a significant share of full CLI scans.The git-diff path also refused outright whenever
branchwasNone, although it never used the branch.Change
GET /api/v1/scans?sha=<c1>,<c2>,...with the usual baseline filters (engine, complete, no PRs, full project state, clean when checksums are unusable) and no branch filter. Up to 3 pages of 50 are read, stopping at the first page with any candidate. Matches are re-checked client-side against the walked commits, because a backend that ignoresshareturns scans of any commit.git_diff_refusalfunction thatplan_git_diffrefuses with, so a later change to when a git diff is allowed (such as Diff the working tree when it is dirty, instead of scanning everything #170) applies to both.shasupport reads the list as one literal commit and returns nothing.scan of ancestor commit abc1234 (N commits back).Backend: Corgea/doghouse#2235, now merged, lets
shatake a comma-separated list, capped at 50 commits. A client-named baseline (incremental_base_shaorincremental_base_scan_id) is not matched against the upload's branch on the server side.Tests
develop-trunk baseline found by ancestry, on both a named branch and a detached HEAD../harness checkpasses: all tests, clippy and format.