Repository navigation
feat(ladder): report the net existing commitment Allocate sized the gap against - #614
Conversation
…ap against Allocate sizes the purchase gap against net existing commitment (existing minus expiring), but the result did not expose that figure, so callers recomputed a gross one from the layer states and a plan's existing figure did not reconcile with its gap. AllocateResult now carries NetExistingUSDPerHour on every successful result, including the hold-only early exits. Net existing is computed right after validation, before the baseline-unavailable hold, so an inconsistent snapshot (expiring above existing) is now an error on that path too instead of a hold. Also correct the BufferReshapeConfig cap docs: since LeanerCloud#605 a nil cap is rejected, not treated as "no cap". Refs LeanerCloud#83 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Brings in main's CI fixes (#1236, #1252) and CI changes since, so this PR gets a fresh CI run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Independent review (IAmJSD's agent, fresh context, given only the diff, the issue and the PR text): VERDICT: APPROVE Blocking:
Non-blocking:
Attacked:
Body-stale:
Reviewer: rB7. Bar while the maintainers are away (set by IAmJSD as acting owner): one approving independent review on the head, two for money, auth and security paths. |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Merged origin/main (now |
|
Local verification at |
This finishes the go part of the 2026-07-28 review bundle. Two earlier PRs already fixed three of the four items. This PR fixes the last one (the go half of the cross-repo
Existingitem) and corrects a doc comment that #605 left stale.Closes #83
Status of each finding on current main (
03f40a3)capOrUnlimitedmaps a nil reshape cap tomath.MaxFloat64on the auto path (providers/aws/ladder/reshape.go)205cf99):requireCaprejects nil andunlimitedCapUSDis gone. Checked on main:reshape.go:100-135. #605 left the doc onladder.BufferReshapeConfigsaying "nil means no cap"; this PR corrects it (pkg/ladder/capability.go).pkg/exchangeruns any mode other than"manual"as auto7da716a):RunAutoExchangeaccepts onlyExchangeModeAuto/ExchangeModeManualand rejects anything else before any store or exchange call (pkg/exchange/auto.go:199-203).CancelPendingExchangesByOriginis logged and ignored, which leaves two live approval tokens7da716a):cancelStalePendingreturns the error and the run stops before it creates any exchange (pkg/exchange/auto.go:218-246).Existing, butAllocatesizes the gap against net (go half: expose the net figure fromAllocate)Root cause and fix (item 4)
Allocatesizes the gap against net existing commitment (existing minus expiring, fromcomputeNetExisting), but it never returned that figure. The platform'sassembleLadderPlantherefore adds up grossExistingUSDPerHourfrom the layer states. The plan'sExistingline in the approval email then doesn't reconcile with its target and gap.AllocateResultgains a newNetExistingUSDPerHour *big.Ratfield. It holds the exactEthe gap was sized against and is set on every successful result, including the target-met and baseline-unavailable holds. The platform reports existing on those holds too.Allocateis split into a thin outer function (validate, compute net existing, then call the innerallocate, then set the field) and the unchanged steps 2-8 inallocate. That way every return path gets the field without touching each early exit, and it stays clear of the lines that fix(ladder): stop subtracting existing commitment from residual baselines #441 rewrites (see Overlap).Verification
All of this is unit-level evidence with in-memory fixtures. No cloud APIs and no DB are involved; the change is pure computation.
Fail-before: I committed the new field without the code that sets it, then ran
go test -count=1 -run 'NetExisting|NilBaselineInconsistent' ./ladder/inpkg:TestAllocate_ReportsNetExisting/{allocation,target_met_hold,baseline_unavailable_hold}: FAIL,NetExistingUSDPerHour is nilTestAllocate_NetExistingReconcilesWithGap: FAIL,NetExistingUSDPerHour is nilTestAllocate_NilBaselineInconsistentSnapshot_Error: FAIL,expected an error for expiring > existing with a nil baseline, got nilPass-after: all 5 pass. The fixture has $10/hr existing on one layer, of which $4/hr expires, plus $2/hr on a second layer. Gross existing is $12/hr and net is $8/hr. The reconcile test checks that planned OD gap +
NetExistingUSDPerHourequals the $20/hr target, which a gross figure would fail ($24 ≠ $20).Commands (with
AWS_CONFIG_FILE=/dev/null AWS_SHARED_CREDENTIALS_FILE=/dev/null AWS_EC2_METADATA_DISABLED=true):go build ./...,go vet ./...andgo vet -tags integration ./...in each of the five modules: cleancd pkg && GOWORK=off go build ./... && GOWORK=off go vet ./ladder/: cleancd pkg && go test -count=1 ./ladder/and the same withGOWORK=off: okcd providers/aws && go test -count=1 ./ladder/(it callsladder.Allocateincommitment_rates_sdk_test.go): okgolangci-lintv2.10.1run --allow-parallel-runners ./ladder/...inpkg: 0 issuesgocyclo -over 10 -ignore "_test\.go" pkg/ladder/allocate.go pkg/ladder/capability.go: nothing over 10git merge-treeof this head against open fix(ladder): stop subtracting existing commitment from residual baselines #441, fix(gcp): fail closed on region-less storage SKUs and ambiguous SKU matches #471, fix(azure): count savings plans billed to another subscription in the duplicate check #491 and fix(azure/compute): skip scope checks on terminal VM reservations #439: all clean. I also merged fix(ladder): stop subtracting existing commitment from residual baselines #441 into a throwaway worktree and rango vetandgo test -count=1 ./ladder/inpkg: okCI-equivalent run on the branch head (
e669581d, up to date with go main03f40a3; Linux, Go 1.26.9,AWS_CONFIG_FILE=/dev/null AWS_SHARED_CREDENTIALS_FILE=/dev/null AWS_EC2_METADATA_DISABLED=true). It's the only go branch in this round, so the combined tree is this branch on main:go test -mod=readonly -race -short -count=1 ./...passes in each module:pkg,providers/aws,providers/azure,providers/gcp.pkgintegration tests (go test -race -tags=integration -short -count=1 ./...) pass.scripts/setup-git-secrets.shpatterns, in a fresh repo with an isolated HOME: the changed files are clean and a planted fake key was flagged.scripts/test-git-secrets-allowlist.sh: 68 PASS, 0 FAIL.Overlap with our open PRs
Allocate. This PR leaves those lines alone, and both merge orders are clean (checked above). One semantic point for whichever PR merges second: under fix(ladder): stop subtracting existing commitment from residual baselines #441's residual basis the gap is sized withE = 0(existingForBasis), whileNetExistingUSDPerHourstill reports existing minus expiring. That is the right figure to display as existing commitment. Strictly, though, the field's doc ("the E Allocate sized the gap against") holds only on the total basis. After both merge, the doc could say so, or fix(ladder): stop subtracting existing commitment from residual baselines #441 could set the field fromgapExisting. Which to do is the owner's call.Out of scope
assembleLadderPlanreportsallocResult.NetExistingUSDPerHourinstead of summing gross layer states) is platform#243. It needs apkgversion that includes this change.netsmap). The platform plan only reports a total, so I left it internal.Please mirror the issue's triage labels onto this PR:
triaged,type/chore,effort/l,priority/p3,severity/low,urgency/eventually,impact/few.Note: the commit message says
Refs #83. The PR body usesCloses #83because, with #578 and #605 already merged, this PR completes the go part of the issue.🤖 Generated with Claude Code