Subchapter 27.37
references/phases/estimate/estimate.mdMarkdown11 KBView on GitHub
Execute ALL steps in order. Do not skip or optimize.
Before running any sub-estimate file, determine the pricing source.
Read shared/pricing-cache.md. Check the Last updated date in the header:
Before any sub-estimate file runs, display the pricing mode to the user so they know what to expect:
pricing_source: unavailable in the estimate.”This prevents silent failures — the user sees the pricing constraint upfront, not after 5 minutes of estimation work.
Each sub-estimate file uses this lookup order per service:
shared/pricing-cache.md (primary) — Cached prices (±5-25% accuracy). Set pricing_source: "cached". Used first because it requires zero API calls and covers most common services.pricing_source: "unavailable" for that service. Add the service to services_with_missing_fallback and display a warning to the user: “Pricing unavailable for [service] — not in cache. Exclude from totals or provide a manual estimate.”pricing_source values summary:
| Value | Meaning |
|---|---|
"cached" | Found in pricing-cache.md (normal path) |
"unavailable" | Not in cache; service excluded from totals |
If cache is > 90 days old:
$MIGRATION_DIR/.phase-status.json. If missing, invalid, or phases.clarify is not exactly "completed": STOP. Output: “Phase 2 (Clarify) not completed or phase state is missing/invalid. Complete Clarify before Estimate.”$MIGRATION_DIR/preferences.json. If missing: STOP. Output: “Phase 2 (Clarify) not completed. Run Phase 2 first.”Check which design artifacts exist in $MIGRATION_DIR/:
aws-design.json (infrastructure design from IaC)aws-design-ai.json (AI workload design)aws-design-billing.json (billing-only design)If none of these artifacts exist: STOP. Output: “No design artifacts found. Run Phase 3 (Design) first.”
IF aws-design.json exists:
Load
estimate-infra.md
Produces: estimation-infra.json
IF aws-design-billing.json exists AND aws-design.json does NOT exist:
Load
estimate-billing.md
Produces: estimation-billing.json
IF aws-design-ai.json exists:
Load
estimate-ai.md
Produces: estimation-ai.json
Before marking Estimate complete, enforce route output gates (fail closed):
aws-design.json existsaws-design-billing.json exists AND aws-design.json does NOT existaws-design-ai.json existsestimation-infra.jsonestimation-billing.jsonestimation-ai.jsonLoad shared/handoff-gates.md. Re-read from disk each active estimate artifact before checking.
Re-entry guard: If generation-infra.json (or sibling generation artifacts) exists and phases.generate is not "pending": STOP unless the user explicitly confirms re-running Estimate. Emit GATE_FAIL | phase=estimate | field=generation-infra.json | reason=stale_downstream.
Infra route additional checks (when estimation-infra.json exists):
recommendation.path ∈ {migrate_optimized, migrate_phased, stay}recommendation.path_label is non-emptyrecommendation.migrate_if and recommendation.stay_if are non-empty arraysOn any FAIL: Emit GATE_FAIL | phase=estimate | field=<path> | reason=missing. Do NOT modify artifacts to pass the gate. Do NOT update .phase-status.json. Tell the user to re-run estimate-infra.md Part 7 (recommendation block).
On PASS: Emit HANDOFF_OK | phase=estimate | artifacts=<comma-separated active estimate files>.
When Estimate is invoked from workshop-refresh.md (inner reprice): write the
estimate artifact(s), present a brief summary, then return to the workshop
loop. Do not emit HANDOFF_OK, do not update .phase-status.json, do
not offer the what-if workshop below.
After outer-run HANDOFF_OK, use the Phase Status Update Protocol
(read-merge-write) — in the same turn as the summary:
phases.estimate to "completed"phases.workshop exists (seed "pending" if missing)current_phase to "generate" — Generate is opt-in from
here on. Leave current_phase at "estimate" and present the Decision
gate below.The decision is the product; execution artifacts are opt-in. The verdict
(recommendation.outcome / path) already exists in the estimate artifacts —
present it and let the user choose what happens next. Never advance to
Generate without an explicit choice of option C (or an explicit later request
for Terraform/scripts).
Present (values from the active estimate artifacts; one line each):
Phase 4 of 6 complete (Estimate). Remaining: Generate (+ optional Feedback).
### Decision pack ready
- Verdict: [outcome_label when recommendation.outcome exists; else path_label]
- AWS estimate (Balanced): $[X]/mo · Your GCP baseline: [figure with its
baseline-quality label from estimate-infra.md Part 1 — apply the
not-comparable rule when the sources measure different things]
- Timeline if you execute: ~[N–M] weeks ([complexity tier], from
shared/migration-complexity.md — omit this line when no tier signal exists)
- Deferred to specialists: [BigQuery / other deferred rows, or omit line]
[A] Done for now — I have what I need to decide
[B] Explore what-ifs — reprice scenarios side by side (~1 min each): region,
single-AZ database, EKS vs Fargate, Graviton
[C] Generate Terraform and migration scriptsData-justified scenario hint (add one line when applicable): if a material
assumption was defaulted rather than confirmed — most commonly availability
(Multi-AZ, ~2x database cost) — append: “Suggestion: we assumed [assumption];
comparing a [alternative] scenario would bound that assumption before you
commit.” Suggest at most one.
Choice handling:
phases.workshop → "completed" (declined). Then:
references/shared/report-decision-core.md
and render it in decision mode — write
$MIGRATION_DIR/decision-report.html and $MIGRATION_DIR/DECISION.md
per that file’s decision-mode rules (no appendices, no Terraform, CTA
footer). Validate with
python3 "$PLUGIN_ROOT/scripts/validate-migration-report.py" "$MIGRATION_DIR/decision-report.html" --mode decision
and pass --estimation-infra / --estimation-ai / --aws-design when
those files exist so the Cost Optimization gate can fire
(absolute paths — cwd must not be load-bearing) and fix failures before
presenting.run_mode: "decide" and current_phase: "complete" in
.phase-status.json (phases.generate stays "pending" — this
combination means “decision complete, execution available on request”;
see schema-phase-status.md).SKILL.md. Close with:
“Your decision report is saved at decision-report.html (plus a
Slack-friendly DECISION.md). If you decide to migrate, say ‘generate
the Terraform and migration scripts’ — everything is saved and I’ll pick
up from here.”references/phases/workshop/workshop.md. Keep
current_phase: estimate; set phases.workshop → "in_progress". On
workshop exit, return to this gate (options A and C; the workshop’s
active scenario carries into either) — do not advance to Generate directly.phases.workshop → "completed" (declined). Set
run_mode: "decide_and_execute" and current_phase → "generate". Then
run the post-gate feedback checkpoint per SKILL.md and continue to
Generate.For AI-only / billing-only runs (no infra inventory), present the gate without
option B and set phases.workshop → "completed". Prefix the presented gate
with the same breadcrumb line: “Phase 4 of 6 complete (Estimate). Remaining:
Generate (+ optional Feedback).”
Breadcrumbs are emitted only after outer-run HANDOFF_OK — never on GATE_FAIL, never from inner workshop reprices.
shared/pricing-cache.md — Cached AWS + source provider pricing (±5-25%, primary source)This phase covers financial analysis ONLY.
Cost labeling rule (applies to ALL sub-estimate files): All dollar figures presented to the user in chat summaries, report tables, and metric boxes MUST be labeled as “estimated monthly costs” or prefixed with “Est.” — never present raw dollar amounts as if they are exact. This includes the Present Summary output, migration report content, and any user-facing cost references.
FORBIDDEN — Do NOT include ANY of:
~N–M weeks, tier from shared/migration-complexity.md) is allowed; full schedules, week-by-week plans, and runbooks remain Generate-onlyYour ONLY job: Show the financial picture of moving to AWS. Nothing else.