Propagate cancellation through audit analysis soft-failure paths - #46998
Conversation
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Ensures audit analysis consistently propagates context cancellation through soft-failure paths.
Changes:
- Returns cancellation after analysis group completion.
- Propagates cancellation from job-detail and generic analysis workers.
- Adds regression coverage for in-flight cancellation.
Show a summary per file
| File | Description |
|---|---|
pkg/cli/audit.go |
Propagates cancellation through audit analysis paths. |
pkg/cli/audit_concurrency_test.go |
Tests canceled soft-failure behavior. |
Review details
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 2/2 changed files
- Comments generated: 0
- Review effort level: Medium
|
✅ PR Code Quality Reviewer completed the code quality review. |
|
🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅ |
|
✅ Test Quality Sentinel completed test quality analysis. |
|
✅ Design Decision Gate 🏗️ completed the design decision gate check. No ADR enforcement needed: PR does not have the 'implementation' label and has ≤100 new lines of code in business logic directories (34 additions detected). |
There was a problem hiding this comment.
The fix is correct and well-targeted. The three changes complement each other: soft-failure paths in launchJobDetailsAnalysis and runAuditAnalysis now surface gctx.Err() when the context is cancelled, and the collectAuditAnalysisResults post-wait guard closes the remaining success-on-cancel window when all goroutines returned nil. The regression test validates the new behavior concurrently. No blocking issues found.
🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · 12.1 AIC · ⌖ 4.34 AIC · ⊞ 5K
There was a problem hiding this comment.
Skills-Based Review 🧠
Applied /tdd and /diagnosing-bugs — one finding, overall solid work.
📋 Key Themes & Highlights
Finding
- Partial test coverage:
runAuditAnalysiscancellation is now tested, but the identical soft-failure+cancel branch inlaunchJobDetailsAnalysishas no regression test.
Positive Highlights
- ✅ Clean, minimal fix — each change is a precise 3-line guard closing the identified gap.
- ✅ The post-
g.Wait()ctx.Err()check incollectAuditAnalysisResultscorrectly handles the silent soft-fail-on-cancel scenario. - ✅ New test uses a blocking channel to reliably reproduce the race without flakiness.
- ✅ PR description is clear and self-contained.
🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · 18.7 AIC · ⌖ 4.5 AIC · ⊞ 6.7K
Comment /matt to run again
| t.Fatalf("expected context canceled error for canceled context soft failure, got %v", err) | ||
| } | ||
| if called { | ||
| t.Fatal("expected setter not to be called when context is canceled") |
There was a problem hiding this comment.
[/tdd] The new test covers the runAuditAnalysis cancellation path well, but the analogous soft-failure cancellation path in launchJobDetailsAnalysis (audit.go line 749–751) has no equivalent test. That branch has the same shape and the same risk.
💡 Suggested test sketch
Add a test that sets up a fake fetchJobDetailsWithCounts that blocks until gctx is done, then returns an error, and asserts g.Wait() returns context.Canceled. The pattern is identical to TestRunAuditAnalysisReturnsCancellationForSoftFailuresWhenContextCanceled.
@copilot please address this.
🧪 Test Quality Sentinel Report❌ Test Quality Score: 80/100 — Needs Review (Build Tag Violation)
📊 Metrics (1 test)
|
There was a problem hiding this comment.
❌ Test Quality Sentinel: 80/100. Hard violation detected: new/modified Go test file missing mandatory //go:build tag on line 1. Test quality is excellent (100% design tests, strong edge-case coverage), but the coding-guideline violation must be resolved before merge. See the sentinel comment above for details.
There was a problem hiding this comment.
Non-blocking observation
The post-g.Wait() context check is the correct and complete fix for the cancellation gap. The in-goroutine guards are a nice-to-have but only trigger when workers return a non-nil error — workers that return nil on graceful shutdown still rely on the outer check. See inline comment for details.
🔎 Code quality review by PR Code Quality Reviewer · 41 AIC · ⌖ 6.03 AIC · ⊞ 5.6K
Comment /review to run again
Comments that could not be inline-anchored
pkg/cli/audit.go:11
Goroutine-level cancellation check is incomplete: If a worker's fn() returns nil on cancellation (by observing <-gctx.Done() internally and returning nil, zero), the checks at lines 20–21 and 30–31 are never reached — the post-g.Wait() check (line 9–11) is the only guard that catches this case.
<details>
<summary>💡 Details</summary>
The inner-goroutine pattern:
if gctx.Err() != nil {
return gctx.Err()
}
auditLog.Printf(...) // soft-failure pathonly triggers when `…
|
🎉 This pull request is included in a new release. Release: |
This follow-up addresses a cancellation gap in the
errgroupmigration from #46973: some analysis goroutines could returnnilafter context cancellation, causingcollectAuditAnalysisResultsto report success. The change ensures cancellation is surfaced consistently even when a worker encounters a soft failure during in-flight shutdown.Context cancellation propagation
collectAuditAnalysisResultsnow checksctx.Err()afterg.Wait()and returns cancellation if set.Soft-failure behavior with canceled context
launchJobDetailsAnalysisnow returnsgctx.Err()when cancellation is active instead of swallowing errors as non-fatal.runAuditAnalysisnow does the same in its soft-failure branch, preserving existing soft-failure behavior only when the context is still valid.Regression coverage