Repository navigation
feat(plans): plan steps resolve real recommendations and show real counts and prices (tier B of #609) #631
Copy link
Copy link
Open
Labels
effort/xlMulti-week / refactorMulti-week / refactorimpact/manyAffects most usersAffects most userspriority/p1Next up; this sprintNext up; this sprintseverity/highSignificant harmSignificant harmtriagedItem has been triagedItem has been triagedtype/featNew capabilityNew capabilityurgency/this-sprintWithin the current sprintWithin the current sprint
Description
Tier B of #609. The tier A stopgap (#618, #616, merged) made empty plan steps fail loudly and show "No recommendations attached". It did not make plans work: until this issue lands, no plan can complete a step, and "Add Purchases" always returns 409.
Goal
A plan created from recommendations (provider, service, term, payment, target accounts, target coverage, ramp) schedules steps that purchase real recommendations, and the planned-purchases list shows real counts, resource types, upfront cost and savings instead of placeholders.
Proposed shape
- Resolve the matching stored recommendations for the plan's provider, service, term, payment and target accounts at execution time, not at plan creation, so a step buys what is current when it runs.
- Size each step from the ramp:
PercentPerStepof the resolved set, per the target-coverage meaning chosen under D1. - Savings Plans steps are sized by
HourlyCommitment, not instance count. - Store the resolved recommendations on the execution, so approval, history and retry see the same rows.
- Planned-purchases preview: compute count, resource types, upfront and savings for pending steps from the current matching recommendations, labelled as an estimate until the step runs.
- Reuse
createPurchaseExecutionsTx(ramp lock #1861, creator stamp sec(auth): API key permission constraints are silently dropped on create #950), which tier A kept without a production caller. Re-enable "Add Purchases" through it. - Decide the dropped
recommendationsfield ofPlanRequest: honour it (per D2) or stop sending it fromsavePlan(frontend/src/plans.ts). - Keep the tier A guards as the fallback: a step that resolves to nothing fails once and does not advance the ramp.
Open product decisions (block the design)
- D1. Does "target coverage 80%" mean "buy 80% of the matching recommendations" or "reach 80% account coverage"? The second needs a coverage source, which is unknown for Azure.
- D2. Is the snapshot sent by "Plan from N selected" binding, or does the plan filter win?
Known gaps to cover
- Recommendations with no account (Azure org-wide) never match a
cloud_account_id = ANY(...)filter (buildRecommendationFilter). The step resolution must decide how to treat them, and the Opportunities page applies suppressions, account overrides and provider/allowed-account filters on top of the stored list; the plan path must match. - Completed empty rows from before tier A already advanced the ramp. Count them with
status='completed' AND recommendations='[]' AND plan_id IS NOT NULL; they are left in place. - Auto-Purchase-OFF plans only reach execution through a manual approve/run.
- Dashboard still renders $0 for bare rows (fix(dashboard): upcoming purchases show zeros for plan steps with no recommendations #620).
- Azure costs feeding any preview depend on the go#267 unit fix being re-pinned (sec(azure): purchase spend caps and recorded Azure costs use lookback-window amounts (cap can be exceeded; stale rows after the fix) #612).
Acceptance
- A plan like the one reported (Azure compute, 1 year, 80% target coverage, weekly 25% ramp, one target account, Auto-Purchase on) produces steps with non-zero counts and real upfront and savings figures, and a scheduled step executes against real recommendations.
- A step with nothing to buy fails once, with one failed row, and the ramp does not advance.
- Regression tests use the real data shape of that plan and fail on current main.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
effort/xlMulti-week / refactorMulti-week / refactorimpact/manyAffects most usersAffects most userspriority/p1Next up; this sprintNext up; this sprintseverity/highSignificant harmSignificant harmtriagedItem has been triagedItem has been triagedtype/featNew capabilityNew capabilityurgency/this-sprintWithin the current sprintWithin the current sprint
Activity
fix(plans): point plan-step refusal messages at the open tracking iss…
fix(purchase): scope plan fan-out recommendations to each account (#793)
fix(purchase): release plan-step suppressions only when no purchase c…
test(purchase): pin that post-submission failures keep plan-step supp…
feat(purchase): atomic plan-step claim, shared suppressions and accou…
feat(planstep): resolve a plan step to sized, priced recommendations …
feat(purchase): per-plan step commitment cap, auto-purchase kill swit…
feat(purchase): make notified real and pin the scheduler claim to the…
65 remaining items
test(plans): prove legacy writers recheck plans an editor Save changed
test(plans): prove legacy writers recheck plans an editor Save changed (
fix(purchase): fail a refused ramp step durably and release its suppr…
fix(plans): let never-started legacy ramps size again
fix(purchase): refuse unverified ramp sizing and adoption (#905)
fix(plans): wrap plan card actions on narrow screens (#1069)
feat(plans): show the proposed ramp as a date graph in Create (#1068)
feat(plans): add date-draft and canonical service id libraries (#1067)
cristim commentedon Oct 18, 2026
Claiming: resume-cc-audit, coordinating recovery and completion of the laddering plan editor under the current owner-authorized Cloud Commitments goal. First reconcile preserved B1/B3 work against current main, recover into isolated worktrees, then ship small legacy-save vertical slices. Preserve original dirty and deferred branches. Each PR gets two independent Sol High reviewers, each two passes against the current head, fixes re-reviewed, local verification and green CI before normal merge. [resume-cc-audit]
cristim commentedon Oct 18, 2026
b1a_implementer
C1a helper characterization is published in #1081 at
05ce1c7abba2e9ed96d117c9ccb75f89494eccfb. All 17 helper/bucket cases across three top-level tests passed under race detection, including an independent offline replay. Both targeted sensitivity probes reached their intended assertions and their full scratch manifests were restored. Two independent reviewers approved the exact committed head. CI and the scheduled review remain monitored.The remaining #631 work is still open:
This PR references #631 and does not close the umbrella issue. Scheduling policy is unchanged.
cristim commentedon Oct 18, 2026
resume-cc-audit
PR #1083 supersedes #1082 at
b790891cbb22b4db9db5037085efc1ece527147d. It adds the reviewed 16-case completion/notification clock characterization with whole-row historical timestamp checks. Both independent reviewers approved this exact head; native Docker PostgreSQL cases, the targeted timestamp/deletion probes, lint, build and normal hooks passed locally. Public CI and CodeRabbit review are still pending.This is characterization, with production behavior unchanged and provider/email effects simulated. It does not complete #631: legacy editor save/graph integration and the remaining veto/gate, failure and post-send coverage remain open. The superseded PR is closed unmerged, and its branch/worktree are preserved.
cristim commentedon Oct 18, 2026
c3a-stamp-implementer
Claiming the #631 pool initialization lifetime follow-up: isolate background pool-fill ownership from bounded opening attempts and add focused PostgreSQL cancellation and Close regressions. Source construction only; this does not close #631.
cristim commentedon Oct 18, 2026
Session: codex-s1-alias-implementer
Renewing the #631 scope claim: preserve singleton legacy service aliases in the existing plan Edit merge, with focused regression coverage. Working from the reviewed predecessor.
fix(api): preserve legacy service aliases on plan update (#1123)