Repository navigation
fix(ladder): persist immediate ramp steps as tranches, plan JSON display-only (B1) - #826
Conversation
…an display-only Bump cloud-commitments-go pkg and the providers to ad67030, where every ramp step including AfterDays==0 is a Tranche and TrancheResult.BuyNow is removed. - persistLadderRun already persists every returned Tranche; the immediate step now arrives as a row with scheduled_date = run start, so the next run's in-flight netting (grace-bounded, #824) sees it. - The plan JSON purchase action carries only the immediate step's amount, not the allocation gap; a layer with no immediate step has no purchase action. - total_hourly_commit is the sum of the persisted tranche rows. - Amounts are stored unchanged (on-demand-equivalent $/hr until go#349). No executor exists and flags stay off; the plan is not a purchase path. Refs #118 Refs go#36 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Independent gate review (Opus 5.5, claude-opus-5-5): APPROVE at aedb5aeMoney path (ladder netting). Nothing here purchases: go.mod/go.sum: ad67030387e4 exists on go main (committed 2026-10-12T20:53:19Z, matching pseudo-version Persistence: Local evidence (throwaway Homebrew PostgreSQL 17.11 on 127.0.0.1, db
CI: green on the SHA incl. Integration Tests and Unit Tests. The first pre-commit run failed on the Trivy installer download (transient, before any hook ran); rerun passed. mergeStateStatus CLEAN. Labels mirror #118; body says Refs #118 / Refs go#36. Non-blocking notes: (1) with no executor, the immediate row shows as Scheduled ("scheduled date has passed") and counts in the cumulative planned chart for 24h, then shows Cancelled; that matches the "not executed yet" banner. (2) Daily re-runs re-plan each expired immediate amount through the ramp again, so the live total sits a hair under target once the halving remainder drops below the engine's minimum (seen as 9.990235 of 10 on day 14); it converges when later steps land. Under-commit, not over. |
Refs #118
Refs go#36
Ladder B1: immediate (AfterDays==0) ramp steps are persisted as tranches so in-flight netting sees them. Nothing here enables purchasing: no executor exists, the flags stay off, and the plan JSON is display only (the only future purchase path is tranche -> purchase_executions).
Changes
v0.0.0-20261012205319-ad67030387e4), no replace.internal/server/handler_ladder.go:TrancheResult.BuyNowno longer exists, and every ramp step arrives as a Tranche, so the immediate one is persisted withscheduled_date= run start (immediate = FireAfter <= run start; no migration). Plan JSON: the ActionPurchase amount is the immediate step's amount only (a layer with no immediate step has no purchase action).total_hourly_commitis the sum of the persisted tranche amounts, not the allocation gap. Amounts are stored unchanged: on-demand-equivalent $/hr until go#349 converts them (documented in code, not changed here).Go commits pulled in by the bump (9dae64b..ad67030)
SavingsPlanDetails(grep), so no platform change, but any Azure SP purchase path that deserializes details withoutCurrencywould now fail loudly.Evidence
Real Postgres 17 (throwaway local DB, migrations applied;
LADDER_B1_TEST_DATABASE_URL, falls back to the Postgres container helper in CI):go test -tags integration ./internal/server -run LadderB1passes 8 (incl. subtests).TestExecuteLadderRun_ImmediateStepIsTrancheAndPlanShowsOnlyItand the updated Healthy/MaxActions tests use a mock store.go test ./internal/...7340 passed,make lint0 issues,make tidy-checkok, pre-commit hooks pass,git ls-files -z | xargs -0 git secrets --scanclean under BSD and GNU grep with--register-aws.Not in this PR
Persist-lock PR (in-flight read inside the persist tx), the reconciler, go#349 unit conversion, the executor.
🤖 Generated with Claude Code
Summary by CodeRabbit