Skip to content

fix(providers): fail loud when all Azure/GCP rec services fail - #1215

Merged
cristim merged 5 commits into
mainfrom
fix/cor-03-all-services-failed-guard
Jul 16, 2026
Merged

cristim merged 5 commits into
mainfrom
fix/cor-03-all-services-failed-guard

Conversation

@cristim

@cristim cristim commented Jun 11, 2026 •

Copy link
Copy Markdown
Member

Problem

Closes #1152 (review finding COR-03).

Azure's mergeServiceResults and GCP's per-region collection logged per-service errors at WARN and dropped them, so a collection where every service or region call failed (expired federated credential, tenant-wide throttle, RBAC gap) returned (recs, nil). Downstream, fanOutPerAccount counted the account as succeeded, UpsertRecommendations evicted all previously collected rows for it while inserting zero new ones, and last_collection_error was cleared, so the dashboard silently lost the account's recommendations with no error banner. AWS already had a guard for exactly this hazard (the 08-H4 all-failed guard in providers/aws/recommendations/client.go).

Fix

Port the AWS 08-H4 guard to both providers:

  • Azure (providers/azure/recommendations.go): mergeServiceResults now returns ([]common.Recommendation, error) and fails loud when every attempted service errored. serviceResult gains an attempted flag so services skipped by the params filter are not counted as successes. The savings plans client is a stub that succeeds unconditionally without making any API call, so it is excluded from the guard; otherwise the guard could never fire on a total provider failure. A note on the stub documents flipping the flag back when the Benefits Recommendations API stabilises.
  • GCP (providers/gcp/recommendations.go): collectRegion now reports attempted/failed call counts plus a representative error in regionResult, and the new mergeRegionResults fails loud when every attempted (region, service) call errored across all regions.

Partial failure keeps the previous tolerated behaviour: one successful call is enough to return the successful results with a nil error, with failures logged at WARN as before. With the error propagating, the scheduler counts the account as failed, keeps its stale rows, records last_collection_error, and the freshness banner surfaces.

Tests

  • providers/azure: TestMergeServiceResults_AllAttemptedFailed, _SkippedServicesDoNotMaskTotalFailure, _SavingsPlansStubDoesNotMaskTotalFailure, _PartialFailureStillSucceeds, plus the updated _OrderIsStable.
  • providers/gcp: TestMergeRegionResults_AllAttemptedFailed, _PartialFailureStillSucceeds, _NoAttemptsIsNotAFailure.
  • internal/scheduler: TestFanOutPerAccount_FailedCollectionNotInSucceededAccountIDs pins that a failed collection is never eligible for stale-row eviction.

Ran go build ./... plus go vet/go test ./... in the root module's internal/scheduler package (102 passed) and in the providers/azure (700 passed) and providers/gcp (262 passed) modules. The new merge-level regression tests cannot compile against the pre-fix code (the pre-fix mergeServiceResults returned only a slice and mergeRegionResults did not exist), which is the structural proof they exercise the new fail-loud contract.

Summary by CodeRabbit

  • Bug Fixes
    • Azure and Google Cloud recommendation collection now reports an error when all attempted services or regions fail, instead of appearing successful with no results.
    • Partial failures continue to return successful recommendations.
    • Failed account collections are no longer treated as successful for downstream cleanup eligibility.
  • Tests
    • Added regression coverage for total failures, partial failures, skipped services, and empty attempts.
  • Documentation
    • Clarified behavior for currently unsupported recommendation sources.

@cristim cristim added triaged Item has been triaged priority/p2 Backlog-worthy severity/medium Moderate harm urgency/this-quarter Within the quarter impact/many Affects most users effort/m Days type/bug Defect labels Jun 11, 2026
@coderabbitai

coderabbitai Bot commented Jun 11, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 1 minute

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1eb88b13-cb8a-47da-bf79-07af9a446446

📥 Commits

Reviewing files that changed from the base of the PR and between e43dc8a and a32b8cd.

📒 Files selected for processing (1)
  • internal/scheduler/scheduler_test.go
📝 Walkthrough

Walkthrough

Azure and GCP recommendation collection now reports total attempted-service failures, while scheduler tests verify failed accounts are not marked successful. Azure service inclusion tracking and related regression coverage were updated; an Azure Terraform file tail also changed.

Changes

Recommendation failure guards

Layer / File(s) Summary
Azure all-failed guard
providers/azure/recommendations.go, providers/azure/recommendations_test.go, providers/azure/services/savingsplans/client.go
Azure tracks attempted services separately from skipped or stubbed services and returns an error when every attempted service fails.
GCP all-failed guard
providers/gcp/recommendations.go, providers/gcp/recommendations_test.go
GCP aggregates regional service outcomes and returns an error for total attempted failure while preserving partial-success behavior.
Scheduler regression coverage
internal/scheduler/scheduler_test.go
Tests ensure failed accounts are excluded from SucceededAccountIDs and Azure all-account failure returns an error with nil recommendations.

Terraform tail update

Layer / File(s) Summary
Federated credential file tail
terraform/environments/azure/ci-cd-permissions/sp.tf
The end of the federated identity credential resource was modified without changing its displayed configuration values.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related issues

  • LeanerCloud/CUDly#1316 — Directly concerns typing and propagating Azure/GCP all-attempted-failed guard errors.

Possibly related PRs

  • LeanerCloud/CUDly#809 — Its Azure savingsplans wiring is directly related to the updated attempted-service accounting.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The Terraform blank-line deletion in sp.tf is unrelated to the recommendation-failure fix. Remove the unrelated Terraform whitespace-only change unless it is intentionally part of this PR.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: failing loud when Azure/GCP recommendation collection fully fails.
Linked Issues check ✅ Passed The Azure/GCP all-failed guard, scheduler propagation, and regression tests address #1152's silent-success bug.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/cor-03-all-services-failed-guard

Comment @coderabbitai help to get the list of available commands.

@cristim

cristim commented Jun 11, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 11, 2026 •

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@cristim
cristim force-pushed the fix/cor-03-all-services-failed-guard branch from c78dd67 to 83d25a7 Compare June 19, 2026 15:29
@cristim

cristim commented Jun 19, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 19, 2026 •

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

cristim added a commit that referenced this pull request Jun 26, 2026
…tract

TestScheduler_CollectAzureRecommendations_Success was asserting require.NoError
on a managed_identity account whose credential resolution fails in CI -- the
pre-fix shape where every per-service call inside mergeServiceResults silently
returned (empty, nil). The COR-03 fix in this PR makes that case fail loud, so
the test now fails: "Azure: all 1 accounts failed; last error: ... all 4 Azure
recommendation services failed: ...".

Rename to _AllAccountsFailLoud and assert the expected error shape end-to-end
(per-service all-failed wrap, per-account all-accounts-failed wrap, empty
SucceededAccountIDs so the scheduler keeps stale rows). This is exactly the
contract the rest of the PR enforces; keeping require.NoError would have
regressed the property the fix is trying to add.

Adversarial review of #1215.
@cristim

cristim commented Jun 26, 2026

Copy link
Copy Markdown
Member Author

Adversarial review

Goal of this PR: when every attempted Azure / GCP recommendation service call errors, surface that as an error to the caller instead of (empty, nil). Pre-fix the scheduler counted the account as succeeded, evicted its previously collected rows, and cleared last_collection_error.

Findings

P0 -- CI was red on a regression introduced by this PR (fixed in 5f3e6a8).

internal/scheduler/scheduler_test.go::TestScheduler_CollectAzureRecommendations_Success was asserting require.NoError on the exact "managed_identity creds fail in CI -> all 4 Azure services error" shape the fix turns into an error. With the new guard wired up, the test now sees "Azure: all 1 accounts failed; last error: account (): get recommendations: all 4 Azure recommendation services failed: ..." and fails. This is the COR-03 contract working as intended, but the test was not updated alongside the production code, so Unit Tests were red on this PR.

Fix in this push: rename to _AllAccountsFailLoud, assert the expected error shape end-to-end (per-service all-failed wrap, per-account all-accounts-failed wrap, empty SucceededAccountIDs so the scheduler keeps stale rows). Locally go test -run TestScheduler_CollectAzureRecommendations_AllAccountsFailLoud ./internal/scheduler/ passes (slow: managed_identity dials IMDS and waits ~2 min for the timeout, but that latency was already there pre-PR).

The remaining Integration Tests reds (TestPostgresStore_* in internal/config) are pre-existing -- they require a postgres instance that isn't wired into this job and reproduce on main.

P3 / nice-to-have (filed as LeanerCloud/cloud-commitments-go#21).

mergeServiceResults / mergeRegionResults surface the total failure as fmt.Errorf("all %d ... services failed: %w", failures, lastErr). The %w wrap keeps errors.Is(err, context.Canceled) etc. working, but callers can't positively distinguish "every attempted call errored on this provider" from "one network blip on a single service" without parsing the format string. AWS has the same shape (providers/aws/recommendations/client.go:415). Sentinel ErrAllRecServicesFailed across all three providers would make the contract explicit. Out of scope for this PR -- tracking in LeanerCloud/cloud-commitments-go#21.

Things that were right

  • AWS sibling path is already covered. providers/aws/recommendations/client.go mergeServiceResults (line 395) has the identical guard at the service level, and GetRecommendationsForService has the matching all-(term,payment)-failed guard one level down (line 277). The PR closes the Azure/GCP gap, not just adds a new guard.
  • attempted flag is the right shape, not a magic value. Skipped-by-filter is structurally distinct from "attempted and succeeded", so the guard cannot be tricked into firing on a single-service request just because four other services were filtered out. The hardcoded attempted=false for the Azure savingsplans stub and Advisor are documented inline with the exact reason (both swallow errors / always return (recs, nil), so counting their unconditional success as an attempt would keep the guard from ever firing on a total credential failure).
  • ctx.Err() after g.Wait() is preserved in both providers. Cancellation short-circuits before mergeServiceResults / mergeRegionResults, so the all-failed wrap can't shadow a context.Canceled / DeadlineExceeded (per feedback_ctx_cancel_terminal.md and feedback_errgroup_ctx_err.md).
  • Partial failure stays tolerated. One successful service in Azure or one successful (region, service) call in GCP is enough to return its recs with nil error; the failures are still logged at WARN. TestMergeServiceResults_PartialFailureStillSucceeds and TestMergeRegionResults_PartialFailureStillSucceeds pin this.
  • Scheduler end-to-end test. TestFanOutPerAccount_FailedCollectionNotInSucceededAccountIDs correctly pins that a failed collection cannot land in SucceededAccountIDs, which is the property that preserves stale rows.

Minor (not blocking)

  • terraform/environments/azure/ci-cd-permissions/sp.tf deletes one trailing blank line. Unrelated to COR-03; harmless but adds noise to the diff.

Tests run locally on the fix

  • providers/azure: go test -run TestMergeServiceResults -v ./ -- 5 tests pass (Order, AllAttemptedFailed, SkippedServicesDoNotMaskTotalFailure, PartialFailureStillSucceeds, StubsDoNotMaskTotalFailure).
  • providers/gcp: go test -run TestMergeRegionResults -v ./ -- 3 tests pass (AllAttemptedFailed, PartialFailureStillSucceeds, NoAttemptsIsNotAFailure).
  • internal/scheduler: go test -run 'TestScheduler_CollectAzureRecommendations_AllAccountsFailLoud|TestFanOutPerAccount_FailedCollectionNotInSucceededAccountIDs' -v ./internal/scheduler/ -- both pass.
  • go build ./... and go vet ./internal/scheduler/ -- clean.

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jun 26, 2026 •

Copy link
Copy Markdown
Contributor

@cristim Thanks for the detailed adversarial review — the CI regression/fix and the scheduler invariant are especially helpful context. I’ll re-run a full review with this in mind.


✏️ Learnings added
Learnt from: cristim
URL: https://github.com/LeanerCloud/CUDly/pull/1215

Timestamp: 2026-06-26T16:59:24.948Z
Learning: In the Go code under `providers/azure/recommendations.go`, `serviceResult.attempted` is the intended mechanism for distinguishing skipped-by-filter recommendation services from attempted calls; Azure services that unconditionally return success without a real API attempt, such as the savings plans stub and Advisor path described in PR `#1215` discussion, must not count as attempted because they would mask the provider-wide all-failed guard.

Learnt from: cristim
URL: https://github.com/LeanerCloud/CUDly/pull/1215

Timestamp: 2026-06-26T16:59:24.948Z
Learning: In the Go scheduler code under `internal/scheduler`, a failed recommendation collection must never be included in `SucceededAccountIDs`; this invariant preserves stale recommendation rows and keeps `last_collection_error` populated instead of treating the account as successfully refreshed.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

✅ Action performed

Full review finished.

@cristim

cristim commented Jul 9, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 9, 2026 •

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

cristim added a commit that referenced this pull request Jul 10, 2026
…tract

TestScheduler_CollectAzureRecommendations_Success was asserting require.NoError
on a managed_identity account whose credential resolution fails in CI -- the
pre-fix shape where every per-service call inside mergeServiceResults silently
returned (empty, nil). The COR-03 fix in this PR makes that case fail loud, so
the test now fails: "Azure: all 1 accounts failed; last error: ... all 4 Azure
recommendation services failed: ...".

Rename to _AllAccountsFailLoud and assert the expected error shape end-to-end
(per-service all-failed wrap, per-account all-accounts-failed wrap, empty
SucceededAccountIDs so the scheduler keeps stale rows). This is exactly the
contract the rest of the PR enforces; keeping require.NoError would have
regressed the property the fix is trying to add.

Adversarial review of #1215.
@cristim
cristim force-pushed the fix/cor-03-all-services-failed-guard branch from 5f3e6a8 to 3709c00 Compare July 10, 2026 13:43
@cristim

cristim commented Jul 10, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 10, 2026 •

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

cristim added a commit that referenced this pull request Jul 10, 2026
…tract

TestScheduler_CollectAzureRecommendations_Success was asserting require.NoError
on a managed_identity account whose credential resolution fails in CI -- the
pre-fix shape where every per-service call inside mergeServiceResults silently
returned (empty, nil). The COR-03 fix in this PR makes that case fail loud, so
the test now fails: "Azure: all 1 accounts failed; last error: ... all 4 Azure
recommendation services failed: ...".

Rename to _AllAccountsFailLoud and assert the expected error shape end-to-end
(per-service all-failed wrap, per-account all-accounts-failed wrap, empty
SucceededAccountIDs so the scheduler keeps stale rows). This is exactly the
contract the rest of the PR enforces; keeping require.NoError would have
regressed the property the fix is trying to add.

Adversarial review of #1215.
@cristim
cristim force-pushed the fix/cor-03-all-services-failed-guard branch from 3709c00 to e43dc8a Compare July 10, 2026 21:46
@cristim

cristim commented Jul 10, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 10, 2026 •

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

cristim added a commit that referenced this pull request Jul 16, 2026
…tract

TestScheduler_CollectAzureRecommendations_Success was asserting require.NoError
on a managed_identity account whose credential resolution fails in CI -- the
pre-fix shape where every per-service call inside mergeServiceResults silently
returned (empty, nil). The COR-03 fix in this PR makes that case fail loud, so
the test now fails: "Azure: all 1 accounts failed; last error: ... all 4 Azure
recommendation services failed: ...".

Rename to _AllAccountsFailLoud and assert the expected error shape end-to-end
(per-service all-failed wrap, per-account all-accounts-failed wrap, empty
SucceededAccountIDs so the scheduler keeps stale rows). This is exactly the
contract the rest of the PR enforces; keeping require.NoError would have
regressed the property the fix is trying to add.

Adversarial review of #1215.
@cristim
cristim force-pushed the fix/cor-03-all-services-failed-guard branch from e43dc8a to abc9f60 Compare July 16, 2026 19:31
cristim added a commit that referenced this pull request Jul 16, 2026
…tract

TestScheduler_CollectAzureRecommendations_Success was asserting require.NoError
on a managed_identity account whose credential resolution fails in CI -- the
pre-fix shape where every per-service call inside mergeServiceResults silently
returned (empty, nil). The COR-03 fix in this PR makes that case fail loud, so
the test now fails: "Azure: all 1 accounts failed; last error: ... all 4 Azure
recommendation services failed: ...".

Rename to _AllAccountsFailLoud and assert the expected error shape end-to-end
(per-service all-failed wrap, per-account all-accounts-failed wrap, empty
SucceededAccountIDs so the scheduler keeps stale rows). This is exactly the
contract the rest of the PR enforces; keeping require.NoError would have
regressed the property the fix is trying to add.

Adversarial review of #1215.
@cristim
cristim force-pushed the fix/cor-03-all-services-failed-guard branch from abc9f60 to 2698cf8 Compare July 16, 2026 19:37
@cristim

cristim commented Jul 16, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@cristim

cristim commented Jul 16, 2026

Copy link
Copy Markdown
Member Author

Merge-prep bot: rebased onto main (73166c2). Added fixup commit to correct British English spellings (stabilises->stabilizes, behaviour->behavior) flagged by misspell linter on new lines. Gates: build_azure=0 build_gcp=0 build_root=0; vet_azure=0 vet_gcp=0 vet_scheduler=0; gocyclo=0 (all touched files); lintnew_azure=0 lintnew_gcp=0; test_azure=700 test_gcp=262 test_scheduler=102 (all passed).

@coderabbitai

coderabbitai Bot commented Jul 16, 2026 •

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

cristim added 5 commits July 16, 2026 23:17
Azure mergeServiceResults and the GCP per-region collection logged
per-service errors and dropped them, so a collection where every
service or region call failed (expired federated credential,
tenant-wide throttle, RBAC gap) returned (recs, nil). The scheduler
then counted the account as succeeded, UpsertRecommendations evicted
all of its previously collected rows while inserting zero new ones,
and last_collection_error was cleared, leaving no signal on the
dashboard.

Port the AWS 08-H4 all-failed guard to both providers:

- Azure: mergeServiceResults now returns an error when every attempted
  service errored. Services skipped by the params filter carry an
  attempted flag so a filtered run cannot mask a total failure, and the
  savingsplans stub (which succeeds unconditionally without any API
  call) is excluded from the guard so it cannot mask one either.
- GCP: collectRegion reports attempted/failed counts plus a
  representative error, and the new mergeRegionResults fails loud when
  every attempted (region, service) call errored across all regions.

Partial failure keeps the previous tolerated behaviour: any single
successful call still returns its recommendations with a nil error.

Regression tests cover the all-attempted-failed, partial-failure,
filter-skip, savingsplans-stub, and zero-attempt shapes, plus a
scheduler-side test asserting a failed collection never lands in
SucceededAccountIDs (the eviction eligibility list).

Closes #1152
getAdvisorRecommendations swallows pagination errors: when the Azure
credential is expired, the auth failure surfaces during pager.NextPage
rather than during client construction, so the function always returns
(recs, nil) even on a hard auth failure. With advisor carried as
attempted=true, the all-attempted-failed guard introduced for COR-03
could never fire on a real total credential failure -- the four real
services would each fail (failures=4, attempted=5) and the guard
condition failures==attempted would remain false.

Fix: set advisor attempted=false, matching the savingsplans exclusion
and its rationale. The guard now fires when the four real reservation
services (compute, database, cache, cosmosdb) all fail. Update the
four guard-behaviour tests to use the production shape (SP=false,
advisor=false) and adjust the expected "all N services failed" counts
from 5-6 down to 4. Also apply the end-of-file trailing-newline fix
pre-commit auto-staged for sp.tf.
…tract

TestScheduler_CollectAzureRecommendations_Success was asserting require.NoError
on a managed_identity account whose credential resolution fails in CI -- the
pre-fix shape where every per-service call inside mergeServiceResults silently
returned (empty, nil). The COR-03 fix in this PR makes that case fail loud, so
the test now fails: "Azure: all 1 accounts failed; last error: ... all 4 Azure
recommendation services failed: ...".

Rename to _AllAccountsFailLoud and assert the expected error shape end-to-end
(per-service all-failed wrap, per-account all-accounts-failed wrap, empty
SucceededAccountIDs so the scheduler keeps stale rows). This is exactly the
contract the rest of the PR enforces; keeping require.NoError would have
regressed the property the fix is trying to add.

Adversarial review of #1215.
Misspell linter (--new-from-rev=origin/main) flagged three British
spellings introduced by the COR-03 commit: "stabilises" in
providers/azure/recommendations.go and "behaviour" in both
providers/azure/recommendations_test.go and
providers/gcp/recommendations_test.go.  Changed to American English
("stabilizes", "behavior") to keep the misspell gate clean.
The standalone "Lint Code" CI job runs full golangci-lint on the root
module, which caught a British "behaviour" in a comment this PR added
at internal/scheduler/scheduler_test.go:1486 (the --new-from-rev
provider sweep did not cover the root module). Changed to "behavior"
so the root golangci misspell gate is clean.
@cristim
cristim force-pushed the fix/cor-03-all-services-failed-guard branch from 2698cf8 to a32b8cd Compare July 16, 2026 20:17
@cristim

cristim commented Jul 16, 2026

Copy link
Copy Markdown
Member Author

Merge-prep bot: fixed the Lint Code CI failure. The standalone "Lint Code" job runs full golangci-lint on the root module (not incremental), which caught a British "behaviour" in a comment this PR added at internal/scheduler/scheduler_test.go:1486; the earlier --new-from-rev provider sweep did not cover the root module. Changed to "behavior".

Grepped the entire PR diff for other British spellings the misspell linter catches (behaviour/colour/optimise/stabilise/cancelled/catalogue/honour/etc.): none remain in added lines.

Full-suite verification matching the CI Lint Code job (true exit codes, no pipe masking):

  • golangci-lint run ./... (root, FULL not --new-from-rev): exit 0, No issues found
  • go vet ./... (root): exit 0
  • gocyclo -over 10 -ignore "_test.go" . (root, exact CI invocation): exit 0, empty
  • providers/azure and providers/gcp golangci --new-from-rev=origin/main: exit 0 (changed-package gate)

Rebased onto latest main (d644f11). Diff intact: 6 files, +358/-40.

@cristim
cristim merged commit 81cd1f4 into main Jul 16, 2026
19 checks passed
@cristim
cristim deleted the fix/cor-03-all-services-failed-guard branch July 16, 2026 20:56
@cristim

cristim commented Jul 16, 2026

Copy link
Copy Markdown
Member Author

Merged to main (rebased onto current main, CLEAN + all CI green; closes #1152). fail loud when ALL Azure/GCP recommendation services fail instead of returning an empty success (no-silent-fallback on the money-adjacent recs path).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/m Days impact/many Affects most users priority/p2 Backlog-worthy severity/medium Moderate harm triaged Item has been triaged type/bug Defect urgency/this-quarter Within the quarter

Projects

None yet

Development

Successfully merging this pull request may close these issues.

COR-03: Azure/GCP collection reports success when every service failed, evicting prior rows

1 participant