If only safe-default gaps remain → disclose defaults and proceed to Phase 2
Single-service shortcut
skip this table for single-service estimates where all parameters are specified
Phase 2 — Estimation
Query
— run the pricing script for each service using parameters from service files + user input + resolved defaults
Calculate
— apply cost formulas from service files; multiply by quantities
Verify arithmetic
— for each line item, restate the formula with actual numbers, compute, and confirm the result. If any intermediate calculation involves multiplication of two numbers > 10, compute it step-by-step (e.g.,
). Do not rely on mental math for multi-digit operations.
Present
— output the estimate with:
Assumptions block
(see Disambiguation Protocol in shared.md) — listed before cost numbers
Line items
service, unit price, quantity/hours, monthly cost
Grand total
re-sum all line-item monthly costs independently; if discrepancy, use re-summed value
Post-Estimate Iteration
After presenting the estimate, the user may request changes (switch region, add RI, resize instances, add/remove services). Re-run only the affected queries — do not restart the full workflow.
Reference Index (load on demand)
Condition
Read
Always (entry point)
references/shared.md
— constants, category index, alias lookup
Query returned 0 results or wrong data
references/pitfalls.md
— troubleshooting and traps
User asks about Reserved Instances or savings plans
references/reserved-instances.md
Non-USD currency or non-eastus region
references/regions-and-currencies.md
User requests private endpoints or private access — confirm PE intent with user
references/services/networking/private-link.md
— PE pricing,
references/services/networking/private-dns.md
— DNS zone pricing
File search returned 0 or ambiguous results
references/service-routing.md
- implemented services routing
First time running scripts or unfamiliar with parameters
references/workflow.md
— script parameters and output formats
Critical Rules
Never guess prices
— always run the script against the live API
Infer currency and region from user context
— if unspecified, ask the user or default to USD and eastus
Ask before assuming
— if a required parameter is ambiguous or missing (tier, SKU, quantity, currency, node count, traffic volume), stop and ask the user. At the request level, clarify vague inputs (Step 2). At the parameter level, apply the Disambiguation Protocol (Step 5).
Default output format is Json
— never use Summary (invisible to agents)
Lazy-load service references
— only read files from
references/services/
directly required by the user's query. Use the file-search workflow (Step 2) to locate specific files.
PowerShell: use
-File
, not
-Command
— run scripts with
pwsh -File
or
powershell.exe -File
; on Linux/macOS, bash strips OData quotes from inline commands.
PS 5.1 caveat:
use
-Command
instead of
-File
when passing array parameters (e.g.,
-Region 'eastus','australiaeast'
), because
-File
mode does not parse PowerShell expression syntax and collapses the array into a single string.
Use exact category names
— group line items using the exact Category Index names from shared.md verbatim (e.g., "Compute", "Databases", "AI + ML"). Do not paraphrase, abbreviate, or rename them.
Scope to user-specified resources
— only include resources explicitly stated in the user's architecture. Companion resources from
billingNeeds
are included automatically.
Service File Metadata
YAML front matter fields. Optional fields use default elision — omitted means the default applies.
Field
Required
Default
Action
billingNeeds
—
omit
Read and price listed dependency services
billingConsiderations
—
omit
Ask user about listed pricing factors before calculating
primaryCost
✔
—
One-line billing summary for quick cost context
apiServiceName
—
omit
Use instead of
serviceName
in API queries
hasMeters
—
true
false
→ skip API, use Known Rates table
pricingRegion
—
regional
global
→
Region: Global
;
api-unavailable
→ skip API;
empty-region
→ omit region
hasKnownRates
—
false
true
→ file contains manual pricing table
hasFreeGrant
—
false
true
→ apply free grant deduction from Cost Formula
privateEndpoint
—
false
true
→ aggregate PE costs via
networking/private-link.md
Universal Traps
These apply to EVERY query:
serviceName
and all filter values are case-sensitive
— use exact values from service reference files
Unfiltered queries return mixed SKU variants
— always filter with
productName
/
skuName
to the specific variant needed
Multi-meter resources need separate queries
— run one query per meter with
-MeterName
Batch Estimation Mode
When estimating
3 or more services
, use these rules to reduce token consumption:
Partial reads
— read only lines 1–45 of each service file (YAML front matter, trap, first query pattern).
Front matter routing
— use YAML metadata to skip unnecessary work:
hasMeters: false
/
pricingRegion: api-unavailable
→ skip API; use Known Rates or
primaryCost
pricingRegion: global
→
Region: Global
;
empty-region
→ omit region
apiServiceName
→ use instead of
serviceName
in queries
hasFreeGrant: true
→ apply grant deduction;
privateEndpoint: true
→ add PE line item
Full read triggers
— no query pattern in partial read, non-default config, 0/unexpected results, or
billingConsiderations
applies.
Parallel queries
— run independent service queries in parallel.
Skip redundant references
— read shared.md and pitfalls.md once at the start, not between services.
Progressive distillation
— after each service query returns, emit a summary row before proceeding:
| Category | Service | Resource | Unit Price | Unit | Qty | Monthly Cost | Notes |
Multi-meter services get one row per line item. After all queries complete, assemble the final estimate from the accumulated rows. Do not re-read service files already distilled unless a full read trigger is needed. During Post-Estimate Iteration, replace the distillation row(s) for any re-queried service.