From a41152247c625036f8d32b24fc166f30465b770c Mon Sep 17 00:00:00 2001 From: Logan Kleier Date: Wed, 22 Jul 2026 13:05:05 -0700 Subject: [PATCH] feat(gcp-to-aws): design summary card + GCP baseline-quality labels with not-comparable rule --- .../references/phases/design/design.md | 22 ++++++++++++++++++- .../phases/estimate/estimate-infra.md | 14 +++++++++++- .../generate/generate-artifacts-report.md | 1 + 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/migrate/plugins/migration-to-aws/skills/gcp-to-aws/references/phases/design/design.md b/migrate/plugins/migration-to-aws/skills/gcp-to-aws/references/phases/design/design.md index 1d7ee4e3..f289d903 100644 --- a/migrate/plugins/migration-to-aws/skills/gcp-to-aws/references/phases/design/design.md +++ b/migrate/plugins/migration-to-aws/skills/gcp-to-aws/references/phases/design/design.md @@ -83,7 +83,27 @@ unless the user is already past Generate (see workshop-refresh stale-Generate guard). Leave `phases.design` and `phases.estimate` as `"completed"` and `current_phase` at `"estimate"` while `phases.workshop` is `"in_progress"`. -After outer-run `HANDOFF_OK`, use the Phase Status Update Protocol +### Design summary card (outer runs only — before the phase-status update) + +After outer-run `HANDOFF_OK`, present a compact card built from the design artifact(s) so the user sees what Design decided before costs arrive. Chat only — not a file: + +``` +### Your AWS architecture at a glance + +| GCP service | AWS target | How we chose this | +| ----------- | ---------- | ----------------- | +| [top 3-5 PRIMARY mappings] | [aws_service] | [Standard pairing / Tailored to your setup / Estimated from billing only] | + +[If any resource is "Deferred — specialist engagement":] +Deferred (specialist engagement): [service names] — excluded from automated design and TCO. + +What Estimate answers next: your GCP baseline vs estimated AWS monthly cost +(three scenarios), per-service breakdown, and the migrate/stay recommendation. +``` + +Use the user-facing vocabulary from `design-refs/fast-path.md` for "How we chose this" (**Standard pairing** / **Tailored to your setup** / **Estimated from billing only**) — never raw `deterministic`/`inferred` enum values. Cap the table at 5 rows ("+ N more in the design artifact"). Skip this card entirely on inner workshop reprices. + +After the card, use the Phase Status Update Protocol (read-merge-write) to update `.phase-status.json` — **in the same turn** as the output message below: diff --git a/migrate/plugins/migration-to-aws/skills/gcp-to-aws/references/phases/estimate/estimate-infra.md b/migrate/plugins/migration-to-aws/skills/gcp-to-aws/references/phases/estimate/estimate-infra.md index 7b88c5bb..9121cecf 100644 --- a/migrate/plugins/migration-to-aws/skills/gcp-to-aws/references/phases/estimate/estimate-infra.md +++ b/migrate/plugins/migration-to-aws/skills/gcp-to-aws/references/phases/estimate/estimate-infra.md @@ -75,6 +75,18 @@ Determine the current GCP monthly infrastructure costs. Use the best available s Present the GCP baseline as a total and per-service breakdown, noting which source was used. +**Baseline-quality display label (derived from `current_costs.source` — no new field):** + +| `current_costs.source` | Display label | +| ----------------------- | --------------------------------------------------------------------------------------------------- | +| `"billing_data"` | "Measured from your GCP billing (±5%)" | +| `"inventory_estimate"` | "Estimated from resource configs (±20–30%) — standing charges only; excludes usage-based costs" | +| `"preferences"` | "Your stated spend band from Clarify (midpoint used)" | +| `"user_provided"` | "Your stated figure (unverified)" | +| `"unavailable"` | "No GCP baseline — AWS costs shown without comparison" | + +**Not-comparable rule (hard):** Never present an inventory-only GCP figure side-by-side with a user spend band (or vice versa) as if they measure the same thing — an inventory estimate captures standing charges for discovered resources, not the full bill. When both exist and disagree by more than the accuracy band, show both, labeled, with one line: "These measure different things — the billing figure (or your stated band) is the decision baseline; the inventory figure only covers discovered resources." Every GCP-vs-AWS comparison row states its baseline label. + ### CUD-Aware Baseline (when billing data available) If `billing-profile.json` contains `commitments.has_active_cuds == true`: @@ -591,7 +603,7 @@ Before returning control to `estimate.md`, require: After writing `estimation-infra.json`, present a concise summary to the user: 1. **Pricing source and accuracy**: State whether prices came from cache or live API, and the accuracy range (±5-10% for infrastructure from cache/live, ±15-25% if cache is stale). Example: "Estimates based on cached AWS pricing (2026-03-07), accuracy ±5-10%." -2. GCP baseline vs estimated AWS monthly cost (balanced tier) — one-line comparison +2. GCP baseline vs estimated AWS monthly cost (balanced tier) — one-line comparison, **with the baseline-quality display label from Part 1** (e.g. "GCP baseline $165/mo — measured from your billing (±5%)") 3. Three-tier table: **Premium**, **Balanced**, **Optimized** with estimated monthly costs. Under or beside each label, use the **short subtitles**: Premium — _Highest resilience / highest monthly estimate in this model_; Balanced — _Default scenario; compare GCP to this first_; Optimized — _Lower monthly estimate; reservations / Spot / storage trade-offs assumed_. Add a one-line **How to read**: three figures are **estimated monthly costs** for the same architecture (high → mid → low); **not** three Terraform stacks. When Terraform is generated later, it aligns with **Balanced**. 4. Per-service estimated monthly cost breakdown (balanced tier, 1 line per service) 5. **If billing data available**: Estimated GCP data transfer egress fees. **If billing data NOT available**: "Data transfer cost estimates require GCP billing data." diff --git a/migrate/plugins/migration-to-aws/skills/gcp-to-aws/references/phases/generate/generate-artifacts-report.md b/migrate/plugins/migration-to-aws/skills/gcp-to-aws/references/phases/generate/generate-artifacts-report.md index 8985d62a..ba01f744 100644 --- a/migrate/plugins/migration-to-aws/skills/gcp-to-aws/references/phases/generate/generate-artifacts-report.md +++ b/migrate/plugins/migration-to-aws/skills/gcp-to-aws/references/phases/generate/generate-artifacts-report.md @@ -161,6 +161,7 @@ Source: `aws-design.json`, `generation-infra.json` **Section 3 — Cost Comparison:** - Side-by-side display: Current GCP Monthly vs Estimated AWS Monthly (**Balanced** tier — the default scenario for comparing to GCP) +- **Baseline-quality badge (required):** label the GCP figure using `current_costs.source` and the display-label table in `estimate-infra.md` Part 1 — "Measured from your GCP billing (±5%)" / "Estimated from resource configs (±20–30%, standing charges only)" / "Your stated spend band from Clarify" / "Your stated figure (unverified)". **Never** place an inventory-only GCP figure beside a user spend band without the explicit not-comparable line from `estimate-infra.md` Part 1 — they measure different things. - Percent change (savings or increase) - **Cost labeling rule:** All dollar figures in cost tables and metrics MUST be labeled as estimated monthly costs. Use column headers like "Est. Monthly AWS" or "Estimated Monthly" — never present figures as exact amounts. - **How to read cost tiers (callout box — required when infra estimation with three tiers exists):** The three AWS monthly figures are **estimated monthly costs** for the **same** mapped architecture (same services in `aws-design.json`), not three different generated Terraform stacks. **Order = highest → middle → lowest** monthly estimate in this model. Use **Balanced** as the **primary** row vs GCP; **Premium** and **Optimized** are **bounds** (higher HA / newer skew vs cost-optimization skew). When `terraform/` is present, it implements **one** infrastructure baseline aligned with the **Balanced** cost scenario (see `terraform/README.md` and `migration_summary` output).