audit.py: blob-filter the branch-drift compare against cherry-picks - #337
Conversation
The three-dot develop...main compare lists files changed on main since the merge-base and is blind to cherry-picked promotions - develop may already hold identical content under different commit SHAs (promote/* branches), re-triggering a false forward-sync DRIFT on every audit until a merge promotion realigns the merge-base (HomeAutomation-Config #21 task 4 was worked against exactly this false positive). Post-filter the compare's files by blob equality at the two heads (one recursive trees call per head): content develop already has is not "content develop lacks". Only the remainder raises the DRIFT finding, which now names the lacking files (up to 8) so a residual false positive is cheap to spot downstream. If either tree is truncated the filter is skipped and the unfiltered finding kept, marked as such (conservative). Verified live: HomeAutomation-Config no longer reports the finding (cherry-picked cspell-scope files are blob-identical at both heads; repo audits clean). Genuine positives still fire with named files: homeassistant-purpleair (requirements-test.txt, requirements.txt) and DevKitCIoT (12 files). Fixes#336. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR updates spec/audit.py's branch-drift check to avoid false positives when main contains cherry-picked (patch-equivalent) promotions from develop, by filtering compare results using blob equality at both branch heads.
Changes:
- Post-filters
develop...maincompare results by blob SHA equality atdevelopandmainheads (via recursive tree lookups) to drop cherry-pick noise. - Improves the DRIFT finding output by listing the specific paths that differ (up to 8) instead of only reporting a count.
- Adds a conservative fallback when the tree response is truncated (skips filtering and keeps the unfiltered DRIFT finding).
Uh oh!
There was an error while loading. Please reload this page.
…pare (Copilot #337) compare files[] caps at 300, so blob-filtering only the listed files could return an empty remainder while unlisted files carry real drift - silent suppression. The main-side change set is now computed from the merge-base tree (base->main blob differences, additions and deletions included, uncapped; the compare supplies only the merge-base sha), then blob-filtered against develop as before. Re-verified: HomeAutomation- Config clean, homeassistant-purpleair (2 files) and DevKitCIoT (12 files) unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
…opilot #337) Deletions and renames on main are drift the check flags, but main does not 'carry' those paths - the message now matches the logic (base->main blob differences develop lacks). Docstring aligned. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
… (Copilot #337) Empty compare files[] means develop is merely ahead (no main-side changes since the merge-base) - the common case now short-circuits with no tree fetches, and the truncated-tree fallback always has a non-empty files[] count to report (the dead inner guard is gone). The lead-in comment no longer describes the superseded files[]-as-signal rationale. Re-verified: HomeAutomation-Config clean, homeassistant-purpleair (2) and DevKitCIoT (12) unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
…rding (Copilot #337) A non-dict trees response now degrades to the unfiltered fallback instead of raising; the path maps include submodule pointer entries (type commit) so main-side submodule bumps are not invisible; comments say object SHA (blob or submodule pointer) rather than blob. All three live cases re-verified unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fixes#336: the branch-drift check derived "main carries content develop lacks" from the three-dot compare alone, which lists files changed on main since the merge-base and is blind to cherry-picked (patch-equivalent) promotions. Any repo promoting via cherry-pick branches re-triggered the finding on every audit - HomeAutomation-Config #21's forward-sync task was authored and worked against exactly this false positive.
Fix
Post-filter the compare's
files[]by blob equality at the two heads (onegit/trees?recursive=1call per head, as the issue suggested): a path whose blob SHA matches atdevelopandmainis content develop already has, not content it lacks. Only the remainder raises the DRIFT finding.truncated(very large repos), the filter is skipped and the unfiltered finding is kept, marked "tree too large to blob-filter cherry-pick noise" - conservative, never silently suppressing.Verification (live, read-only)
python3 spec/audit.py HomeAutomation-Config-> clean (previously:DRIFT branch: main carries 2+ changed file(s)...from the cherry-picked cspell-scope promotions; both files are blob-identical at the heads).main carries 2 file(s) develop lacks: requirements-test.txt, requirements.txt; DevKitCIoT ->main carries 12 file(s) develop lacks: .editorconfig, ...(first 8 shown).🤖 Generated with Claude Code