Skip to content

feat(ladder): phase 3 - pipeline (schema, scheduled task, approval/auto modes, UI, terraform) #70

Open

Description

@cristim

Part of LeanerCloud/cloud-commitments-go#27 (commitment laddering automation). Phase 3 of 4: persistence, scheduled task, approval/auto modes, UI, Terraform. All flag-gated default-off.

PRs:

  1. Migrations 000078-000080 + stores: ladder_configs (per cloud_account x provider), ladder_runs (immutable audit: inputs snapshot, plan jsonb with rationales, run-level approval token, status CAS), ladder_tranches; purchase_executions.ladder_run_id + ri_exchange_history.ladder_run_id link columns; global_config.laddering_enabled kill-switch; PurchaseSourceLadder = "cudly-ladder"; store methods in internal/config/store_postgres_ladder.go.
  2. Scheduled task, plan-only: ladder_run task type + dispatch in internal/server/handler.go; handler_ladder.go with cadence self-gate (daily <20h / weekly <6d20h slack); persists planned runs + tranches, applies guardrails; no execution or email yet (safe dry-run milestone).
  3. Email-approval mode: pending purchase_executions + pending reshapes linked to the run; run-level token fan-out approve/cancel endpoints (3-mode auth dispatch, fail-closed); SendLadderRunSummary (SES targeted only, ErrTokenInBroadcast guard); frontend/src/ladder-deeplink.ts.
  4. Auto-approve mode: status=scheduled purchases with fire_at = now + PurchaseDelayHours riding the existing FireScheduledDelayedPurchases sweep (minimally extended for ladder-linked reshapes); pre-notification + SendLadderRunCompleted confirmation.
  5. Settings UI + config API: per-account laddering config editor in settings.ts + /api/ladder/configs CRUD.
  6. Run history/detail UI + Terraform: /api/ladder/runs list/detail (tokens stripped), run detail view with planned-vs-executed actions and rationales; EventBridge rule/target/permission behind enable_ladder_run_schedule (default false), vars threaded through environments/profiles.

Activity

  1. cristim commented on Jul 3, 2026

    @cristim
    MemberAuthor

    Scope note from the phase-1/2 reviews: the engine (#1340) sizes allocations in account-wide $/hr per layer, but executing a purchase needs concrete instrument targeting - an EC2 Instance SP purchase requires family+region, a Convertible RI requires instance type/platform/tenancy/scope (the write side LeanerCloud/cloud-commitments-cli#1349 hard-requires these in the Recommendation). The pipeline's plan-assembly step must translate each layer allocation into concrete recommendations (likely via the existing CE GetReservationPurchaseRecommendation / GetSavingsPlansPurchaseRecommendation parsers, scaled to the tranche amount via common.ScaleRecommendationCosts) before creating purchase_executions. This is the largest engine-to-pipeline seam; budget it explicitly in the ladder_run task PR.

  2. cristim commented on Jul 16, 2026

    @cristim
    MemberAuthor

    Phase-3 PR-2 (#1362, the plan-only ladder_run scheduled task) is merged to main (7adacd715). Now on main: run/tranche store layer with single-tx persistence and typed-status CAS, the ladder_run task with kill-switch + fail-closed cadence gating + fail-loud account/region resolution, plan-only executeLadderRun, and the capability factory seam. In flight toward this issue: LeanerCloud/cloud-commitments-cli#1365 (stale-baseline guard, rebasing on the new factory), LeanerCloud/cloud-commitments-cli#1366 (truncate guardrail), LeanerCloud/cloud-commitments-cli#1368 (scoped reshape cancellation), LeanerCloud/cloud-commitments-cli#1369 (EventBridge ticks). Launching next: L2 (wire real CE/SP/RI read adapters into the factory so runs produce real plans), then the execution chain (write-side wiring, email-approval, auto-approve, tranche firing, reaper, alerting) per the full-automation plan.

  3. cristim commented on Jul 16, 2026

    @cristim
    MemberAuthor

    L2 merged via LeanerCloud/cloud-commitments-cli#1378: the capability factory is now wired to real Cost Explorer / Savings Plans / RI data - scheduled ladder_run invocations produce real plans end-to-end (plan-only). Chain continues with L5 (net in-flight tranches into the gap) and L6 (write-side wiring behind a kill-switch).

  4. cristim commented on Jul 16, 2026

    @cristim
    MemberAuthor

    Phase-3 progress: the ladder write-side wiring landed via LeanerCloud/cloud-commitments-cli#1396 (merged) behind a default-off ladder_execution_enabled kill-switch (fail-closed; spend provably impossible when off). This is the L6 milestone of the pipeline; the umbrella stays open for the remaining phase-3 items (approval/auto-approve modes, settings + run-history UI, terraform EventBridge tick). L5 convergence fix (#1397) is in adversarial review.

  5. cristim commented on Jul 16, 2026

    @cristim
    MemberAuthor

    Phase-3 progress: L5 tranche-netting convergence fix landed via LeanerCloud/cloud-commitments-cli#1397 (merged). The ladder engine now holds compute at the target coverage without the drift-up under-commit. Combined with the L6 kill-switch (#1396), the plan-only + gated write-side pipeline is in place. Remaining phase-3: approval/auto-approve modes, settings + run-history UI, terraform EventBridge tick. Hardening follow-ups: LeanerCloud/cloud-commitments-go#36.

  6. cristim commented on Oct 8, 2026

    @cristim
    MemberAuthor

    Current-main audit at f2d60df86209eea85d81e9091c20832bd670a65f confirms this remains a planning-only feature across the full UI/API/task path:

    Verification: go test ./internal/server -run 'Ladder|Tranche' -count=1 passed on an exact archived live-main tree (mock boundary tests, no cloud calls or purchases). The fake write methods in handler_ladder_test.go:89-102 fail the test if a write is attempted, confirming those tests intentionally protect the plan-only milestone rather than exercise an executor.

    Before enabling an executor, preserve these distinctions in the UI/API: planned vs scheduled vs executed, provider/service support, deployment-account gate, due vs elapsed tranches, updated usage/headroom and current permissions. New independently reproduced read-side issues from this audit are shared-go #282 (residual baseline subtracts existing twice) and platform #660 (accepted 1-6 day lookbacks cannot satisfy AWS baseline's 7-point minimum). No duplicate pipeline issue was opened.

  7. cristim commented on Oct 17, 2026

    @cristim
    MemberAuthor

    Owner decision (2026-10-17): this issue moves from the ladder sessions to the platform implementation driver. #118 is taken first as a concrete fix; #70 is planned as an epic and split into slices of at most 400 lines.

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions