Claude Cursor GitHub Copilot Skill

focus-spec-normalizer

Normalize vendor-specific billing rows (AWS CUR, Azure Cost Management, GCP Billing Export, OCI) into FOCUS v1.2 columns from user-pasted CSV or JSON input. Refuses to invent column values not derivable from the input. No credentials accepted; operates on user-supplied data only.

LLM Mart · 0 points · 0 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download vincentchuwaichow-vanguard-frontier-agentic-skills_finops_focus-spec-normalizer-febe32a.zip · 9 KB
Part of vincentchuwaichow/vanguard-frontier-agentic — 293 skills

Install

skills CLI npx skills add https://github.com/VincentChuWaiChow/vanguard-frontier-agentic/tree/master/skills/finops/focus-spec-normalizer
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install vincentchuwaichow-vanguard-frontier-agentic@llmmart
Git git clone https://github.com/VincentChuWaiChow/vanguard-frontier-agentic.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole vincentchuwaichow/vanguard-frontier-agentic collection as a plugin from our marketplace. Git is the plain clone.

README

FOCUS Spec Normalizer

A FinOps skill that normalizes vendor-specific billing rows into FOCUS v1.2 columns from user-pasted CSV or JSON input. Operates on caller-supplied data only; refuses to invent values not present in the input.

Purpose

Map billing rows from AWS Cost and Usage Report (CUR), Azure Cost Management export, GCP Billing Export, or OCI billing into the FinOps Open Cost and Usage Specification (FOCUS) v1.2 column schema. Each output column is annotated with a provenance label (mapped, derived, or null) and gaps are documented with resolution notes.

Allowed tools

Read Grep Glob

Usage

Single row: Paste one billing row as CSV (with header) or JSON object. The skill detects the vendor from the column names, applies the appropriate mapping, and returns a FOCUS v1.2 JSON object with per-column provenance labels and a gap summary.

Multi-row batch: Paste multiple rows (CSV table or JSON array). The skill maps each row and returns an array of FOCUS objects plus an aggregate gap summary covering all rows.

Trust posture

Read-only. No cloud credentials, billing account IDs, tenant IDs, or tenant-specific data accepted. All input is user-provided; no live cloud API connections are made. The skill will not invent, default, or infer values for FOCUS columns that are absent from the input — absent columns are set to null with a stated reason.

Targets FOCUS v1.2. The FOCUS version is declared in every output.

See SKILL.md for the full mapping behavior, vendor detection logic, and response shape.

Skill manifest

FOCUS Spec Normalizer

Purpose

Map vendor-specific billing row data (pasted as CSV or JSON snippet) to FOCUS v1.2 columns. The output is a FOCUS-normalized row or set of rows that can be ingested by any FinOps tool that accepts FOCUS-formatted data.

No network access. No credentials. All input is user-supplied billing data.

When to use

Use this skill when:

  • The user has pasted one or more billing rows from AWS CUR, Azure Cost Management export, GCP Billing Export, or OCI billing and wants them mapped to FOCUS v1.2 columns
  • The user wants to understand which FOCUS columns can and cannot be populated from a given vendor's billing format
  • The user is building a multi-cloud cost normalization pipeline and needs the column-level mapping documented

Operating rules

  • No credential accepted. No cloud credentials, billing account IDs, tenant IDs, or service principal data are accepted. The user pastes de-identified or sample billing data; no live API connection is made.
  • No invented values. If a FOCUS column cannot be populated from the data in the input row, the output cell is set to null and the reason is stated. Do not infer, default, or fabricate values for required FOCUS columns that are absent from the input.
  • Input format. Accept CSV (with header row) or JSON object/array. State the detected format before mapping.
  • Provenance labels. Every mapped FOCUS column value must carry one label:
    • mapped — value is directly present in the input row under a different column name
    • derived — value is computed from one or more input columns using a documented transformation (state the transformation)
    • null — column cannot be populated from the available input (state why)
  • FOCUS version. This skill targets FOCUS v1.2. State the FOCUS version in every output.
  • Load references only when needed.

Mapping behavior

Step 1: detect vendor

Identify the billing format from the column names present in the input header:

  • AWS CUR: columns include lineItem/UsageType, lineItem/ProductCode, lineItem/BlendedCost, lineItem/UnblendedCost
  • Azure Cost Management: columns include CostInBillingCurrency, ResourceType, SubscriptionId, MeterName
  • GCP Billing Export: columns include service.description, sku.description, cost, usage.amount, project.id
  • OCI: columns include currency/currencyCode, cost/myCost, service/serviceName, product/resourceName

If the vendor cannot be identified from column names, ask one clarifying question.

Step 2: apply vendor-specific mapping

Load the relevant mapping section from references/vendor-mapping.md for the detected vendor, then produce FOCUS v1.2 output columns.

Step 3: flag gaps

For any required FOCUS v1.2 column that cannot be populated, include a gap note:

<FocusColumn>: null
  Reason: <why this column cannot be populated from <vendor> billing data>
  Resolution: <where in the vendor's billing config this data can be enabled, if known>

Response shape

Return:

  1. Detected vendor and input format.
  2. FOCUS v1.2 normalized row(s) in JSON object format.
  3. Provenance label for each column value.
  4. Gap summary table listing columns set to null and resolution notes.
  5. FOCUS version declared: 1.2.

Example output structure:

{
  "FocusVersion": "1.2",
  "ProviderName": "Amazon Web Services",
  "PublisherName": "Amazon Web Services",
  "ServiceCategory": "Compute",
  "ServiceName": "Amazon EC2",
  "ChargeCategory": "Usage",
  "ChargeDescription": "...",
  "ChargeFrequency": "Usage-based",
  "BillingPeriodStart": "2026-04-01T00:00:00Z",
  "BillingPeriodEnd": "2026-05-01T00:00:00Z",
  "BilledCost": 42.50,
  "BilledCurrency": "USD",
  "EffectiveCost": null,
  "ListCost": null,
  "ContractedCost": null,
  "ResourceId": "i-0abc1234def567890",
  "ResourceName": null,
  "SkuId": "RunInstances:0014",
  "SkuPriceId": null,
  "Region": "us-east-1",
  "AvailabilityZone": "us-east-1a",
  "Tags": {}
}

Each field in the output is annotated with its provenance label in the gap summary.

References

Load these only when needed:

Files (vanguard-frontier-agentic)
  • references
    • focus-columns.md 6.3 KB
      # FOCUS v1.2 Column Definitions
      
      Source: https://focus.finops.org/the-current-release/
      
      All columns below are part of the FOCUS v1.2 specification. Required columns must be present in every conformant billing row. Conditional columns are required when the described condition is true. Recommended columns are optional but strongly encouraged.
      
      ## Required columns
      
      | Column | Type | Description | Example |
      |---|---|---|---|
      | `BilledCost` | Decimal | Amount charged to the billing account for the charge after any discounts, credits, and tax. | `42.50` |
      | `BilledCurrency` | String | Currency of BilledCost. ISO 4217 alphabetic code. | `"USD"` |
      | `BillingAccountId` | String | Identifier assigned to a billing account by the provider. | `"123456789012"` |
      | `BillingAccountName` | String | Display name of the billing account. | `"My AWS Account"` |
      | `BillingPeriodEnd` | DateTime (ISO 8601) | Exclusive end date/time of the billing period for the charge. | `"2026-05-01T00:00:00Z"` |
      | `BillingPeriodStart` | DateTime (ISO 8601) | Inclusive start date/time of the billing period for the charge. | `"2026-04-01T00:00:00Z"` |
      | `ChargeCategory` | String (enum) | High-level classification of the charge type. One of: `Usage`, `Purchase`, `Tax`, `Credit`, `Adjustment`. | `"Usage"` |
      | `ChargeDescription` | String | Description of the charge from the provider's billing system. | `"$0.0464 per On Demand Linux m5.large Instance Hour"` |
      | `ChargeFrequency` | String (enum) | How often the charge occurs. One of: `Usage-based`, `Recurring`, `One-time`. | `"Usage-based"` |
      | `ChargePeriodEnd` | DateTime (ISO 8601) | Exclusive end date/time for the period covered by this charge row. | `"2026-04-02T00:00:00Z"` |
      | `ChargePeriodStart` | DateTime (ISO 8601) | Inclusive start date/time for the period covered by this charge row. | `"2026-04-01T00:00:00Z"` |
      | `ConsumedQuantity` | Decimal | Amount of the consumed resource. | `730.0` |
      | `ConsumedUnit` | String | Unit of ConsumedQuantity. | `"Hrs"` |
      | `EffectiveCost` | Decimal | Amortized cost of the charge after all applicable discounts, credits, and amortized upfront fees. | `38.00` |
      | `InvoiceIssuerName` | String | Name of the entity that issued the invoice. Often same as ProviderName. | `"Amazon Web Services, Inc."` |
      | `ListCost` | Decimal | Charge based on the list unit price without any discounts applied. | `46.00` |
      | `ListUnitPrice` | Decimal | Published unit price for the charge without any discounts. | `0.0464` |
      | `PricingCategory` | String (enum) | Describes the pricing model of the charge. One of: `Standard`, `Dynamic`, `Committed`, `Other`. | `"Standard"` |
      | `PricingQuantity` | Decimal | Amount of the charge using the pricing unit. | `730.0` |
      | `PricingUnit` | String | Unit of PricingQuantity. | `"Hrs"` |
      | `ProviderName` | String | Name of the cloud provider. | `"Amazon Web Services"` |
      | `PublisherName` | String | Name of the entity that published the service. Often same as ProviderName. | `"Amazon Web Services"` |
      | `Region` | String | Provider-specific identifier for the geographic area. | `"us-east-1"` |
      | `ServiceCategory` | String (enum) | High-level classification of the service type. One of: `AI and Machine Learning`, `Analytics`, `Business Applications`, `Compute`, `Containers`, `Databases`, `Developer Tools`, `Identity`, `Integration`, `IoT`, `Management and Governance`, `Media`, `Migration`, `Mixed`, `Mobile`, `Networking`, `Other`, `Security`, `Storage`, `Web`. | `"Compute"` |
      | `ServiceName` | String | Display name of the service. | `"Amazon EC2"` |
      | `SkuId` | String | Provider-specific identifier for the SKU. | `"RunInstances:0014"` |
      | `SubAccountId` | String | Identifier for the sub-account (AWS account, Azure subscription, GCP project, OCI compartment). | `"987654321098"` |
      | `SubAccountName` | String | Display name of the sub-account. | `"production-workloads"` |
      
      ## Conditional columns
      
      | Column | Type | Required when | Description |
      |---|---|---|---|
      | `AvailabilityZone` | String | Resource is zonal | Provider zone identifier within a region. |
      | `CommitmentDiscountCategory` | String (enum) | PricingCategory = Committed | Category of the commitment discount: `Spend` or `Usage`. |
      | `CommitmentDiscountId` | String | PricingCategory = Committed | Identifier of the commitment discount instrument. |
      | `CommitmentDiscountName` | String | PricingCategory = Committed | Display name of the commitment discount instrument. |
      | `CommitmentDiscountType` | String | PricingCategory = Committed | Commitment type label (e.g., `Reserved Instance`, `Savings Plan`, `Committed Use Discount`). |
      | `ContractedCost` | Decimal | Contracted price differs from list | Cost at the contracted unit price before discounts. |
      | `ContractedUnitPrice` | Decimal | Contracted price differs from list | Contracted unit price. |
      | `ResourceId` | String | Resource is identifiable | Provider resource identifier. |
      | `ResourceName` | String | Resource has a display name | Display name of the resource. |
      | `ResourceType` | String | Resource type is classifiable | Provider-specific resource type classification. |
      | `SkuPriceId` | String | Provider publishes SKU price IDs | Provider-specific identifier for the unit price of this charge. |
      | `Tags` | Map (String → String) | Tags exist on the resource | Key-value pairs of resource tags. |
      
      ## Recommended columns
      
      | Column | Type | Description |
      |---|---|---|
      | `BillingExchangeRate` | Decimal | Exchange rate applied when converting from pricing currency to billing currency. |
      | `BillingExchangeRateDate` | DateTime (ISO 8601) | Date/time the exchange rate was set. |
      | `InvoiceId` | String | Identifier of the invoice or statement for this charge. |
      
      ## Notes on null handling
      
      FOCUS requires that required columns be present in every conformant row. When a vendor billing format does not supply data for a required FOCUS column, set the value to `null` and document the gap. A null in a required column indicates a normalization gap, not a schema violation, as long as it is disclosed.
      
      For `EffectiveCost`, `ListCost`, and `ContractedCost`: many vendors do not provide all three in their standard export formats. AWS CUR provides `lineItem/UnblendedCost` (≈ ListCost for on-demand, ≈ EffectiveCost for RI/SP amortized), but not a separate ListCost column. Document which cost columns map to which FOCUS columns and note any amortization assumptions.
      
    • vendor-mapping.md 14.9 KB
      # Vendor to FOCUS Column Mapping Tables
      
      ## AWS Cost and Usage Report (CUR) → FOCUS v1.2
      
      AWS CUR column names follow the `<group>/<field>` naming convention (e.g., `lineItem/UnblendedCost`).
      
      | FOCUS column | AWS CUR column(s) | Transformation | Provenance |
      |---|---|---|---|
      | `BilledCost` | `lineItem/BlendedCost` | Direct map. For consolidated billing accounts, blended cost distributes RI/SP savings across linked accounts. For single accounts, use `lineItem/UnblendedCost`. | mapped |
      | `BilledCurrency` | `lineItem/CurrencyCode` | Direct map. | mapped |
      | `BillingAccountId` | `bill/PayerAccountId` | Direct map. | mapped |
      | `BillingAccountName` | Not in standard CUR | null — not exported by AWS; available in AWS Organizations API only. | null |
      | `BillingPeriodStart` | `bill/BillingPeriodStartDate` | Convert to ISO 8601 UTC. | derived |
      | `BillingPeriodEnd` | `bill/BillingPeriodEndDate` | Convert to ISO 8601 UTC. | derived |
      | `ChargeCategory` | `lineItem/LineItemType` | Map: `Usage` → `Usage`; `Tax` → `Tax`; `Credit` → `Credit`; `RIFee` → `Purchase`; `SavingsPlanCoveredUsage` → `Usage`; `SavingsPlanRecurringFee` → `Purchase`; `Refund` → `Credit`; `EdpDiscount` → `Credit`. | derived |
      | `ChargeDescription` | `lineItem/LineItemDescription` | Direct map. | mapped |
      | `ChargeFrequency` | `lineItem/LineItemType` | `RIFee`/`SavingsPlanRecurringFee` → `Recurring`; `Usage` → `Usage-based`; tax/credit/fee → `One-time`. | derived |
      | `ChargePeriodStart` | `lineItem/UsageStartDate` | Convert to ISO 8601 UTC. | derived |
      | `ChargePeriodEnd` | `lineItem/UsageEndDate` | Convert to ISO 8601 UTC. | derived |
      | `ConsumedQuantity` | `lineItem/UsageAmount` | Direct map. | mapped |
      | `ConsumedUnit` | `pricing/unit` | Direct map. | mapped |
      | `EffectiveCost` | `lineItem/UnblendedCost` for on-demand; `savingsPlan/SavingsPlanEffectiveCost` or `reservation/EffectiveCost` for committed. | Map on-demand rows directly; for RI/SP rows, use the amortized effective cost columns. | derived |
      | `InvoiceIssuerName` | Static: `"Amazon Web Services, Inc."` | Fixed value for all AWS CUR rows. | derived |
      | `ListCost` | `pricing/publicOnDemandCost` | Direct map when present; null if column not enabled in CUR config. | mapped |
      | `ListUnitPrice` | `pricing/publicOnDemandRate` | Direct map when present; null if column not enabled. | mapped |
      | `PricingCategory` | `lineItem/LineItemType` | `Usage` → `Standard`; `SavingsPlanCoveredUsage`/`DiscountedUsage` → `Committed`; `Spot` → `Dynamic`; other → `Other`. | derived |
      | `PricingQuantity` | `lineItem/UsageAmount` | Same as ConsumedQuantity for most rows. | mapped |
      | `PricingUnit` | `pricing/unit` | Direct map. | mapped |
      | `ProviderName` | Static: `"Amazon Web Services"` | Fixed value. | derived |
      | `PublisherName` | Static: `"Amazon Web Services"` | Fixed value. | derived |
      | `Region` | `product/region` | Direct map. | mapped |
      | `ServiceCategory` | `lineItem/ProductCode` | Map product code to FOCUS ServiceCategory (see note below). | derived |
      | `ServiceName` | `product/ProductName` | Direct map. | mapped |
      | `SkuId` | `lineItem/UsageType` | Direct map. | mapped |
      | `SkuPriceId` | Not in standard CUR | null — AWS does not export a SkuPriceId equivalent in CUR. | null |
      | `SubAccountId` | `lineItem/UsageAccountId` | Direct map. | mapped |
      | `SubAccountName` | Not in standard CUR | null — account name not in CUR; available via Organizations API. | null |
      | `AvailabilityZone` | `lineItem/AvailabilityZone` | Direct map when present. | mapped |
      | `ResourceId` | `lineItem/ResourceId` | Direct map when present (requires resource IDs enabled in CUR). | mapped |
      | `ResourceName` | Not in standard CUR | null — resource names not exported by AWS CUR. | null |
      | `ResourceType` | `product/instanceType` or `product/productFamily` | Use `product/instanceType` for compute; `product/productFamily` otherwise. | derived |
      | `Tags` | `resourceTags/<user:key>` columns | Flatten `resourceTags/user:<key>` column prefix to map of key-value pairs. | derived |
      
      ### AWS ServiceCategory mapping
      
      | AWS ProductCode | FOCUS ServiceCategory |
      |---|---|
      | `AmazonEC2` | Compute |
      | `AmazonEKS` | Containers |
      | `AmazonECS` | Containers |
      | `AmazonS3` | Storage |
      | `AmazonRDS` | Databases |
      | `AmazonDynamoDB` | Databases |
      | `AmazonCloudFront` | Networking |
      | `AmazonVPC` | Networking |
      | `AWSLambda` | Compute |
      | `AmazonBedrock` | AI and Machine Learning |
      | `AmazonSageMaker` | AI and Machine Learning |
      | `AmazonRedshift` | Analytics |
      | `AmazonAthena` | Analytics |
      | `AWSGlue` | Analytics |
      | `AmazonSNS` | Integration |
      | `AmazonSQS` | Integration |
      | Other | Other |
      
      ---
      
      ## Azure Cost Management Export → FOCUS v1.2
      
      Azure Cost Management export columns vary by export type (ActualCost vs AmortizedCost). The table below assumes the standard ActualCost export schema.
      
      | FOCUS column | Azure Cost Management column(s) | Transformation | Provenance |
      |---|---|---|---|
      | `BilledCost` | `CostInBillingCurrency` | Direct map. | mapped |
      | `BilledCurrency` | `BillingCurrencyCode` | Direct map. | mapped |
      | `BillingAccountId` | `BillingAccountId` | Direct map. | mapped |
      | `BillingAccountName` | `BillingAccountName` | Direct map. | mapped |
      | `BillingPeriodStart` | `BillingPeriodStartDate` | Convert to ISO 8601 UTC. | derived |
      | `BillingPeriodEnd` | `BillingPeriodEndDate` | Convert to ISO 8601 UTC. | derived |
      | `ChargeCategory` | `ChargeType` | Map: `Usage` → `Usage`; `Purchase` → `Purchase`; `Tax` → `Tax`; `Refund` → `Credit`; `Adjustment` → `Adjustment`. | derived |
      | `ChargeDescription` | `MeterName` + `MeterCategory` | Concatenate: `<MeterCategory> - <MeterName>`. | derived |
      | `ChargeFrequency` | `ChargeType` | `Usage` → `Usage-based`; `Purchase` → `Recurring` or `One-time` depending on Frequency field. | derived |
      | `ChargePeriodStart` | `Date` | Parse as start of day UTC. | derived |
      | `ChargePeriodEnd` | `Date` | Parse as end of day UTC (start + 24h). | derived |
      | `ConsumedQuantity` | `Quantity` | Direct map. | mapped |
      | `ConsumedUnit` | `UnitOfMeasure` | Direct map. | mapped |
      | `EffectiveCost` | `CostInBillingCurrency` for ActualCost export; `AmortizedCost` for AmortizedCost export. | For RI/savings plan amortization, use the AmortizedCost export. | mapped/derived |
      | `InvoiceIssuerName` | Static: `"Microsoft"` | Fixed value. | derived |
      | `ListCost` | `PayGPrice` × `Quantity` when both available | Multiply if PayGPrice column is present. | derived |
      | `ListUnitPrice` | `PayGPrice` | Direct map when present. | mapped |
      | `PricingCategory` | `PricingModel` | Map: `OnDemand` → `Standard`; `Spot` → `Dynamic`; `Reservation` → `Committed`; `SavingsPlan` → `Committed`. | derived |
      | `PricingQuantity` | `Quantity` | Direct map. | mapped |
      | `PricingUnit` | `UnitOfMeasure` | Direct map. | mapped |
      | `ProviderName` | Static: `"Microsoft Azure"` | Fixed value. | derived |
      | `PublisherName` | `PublisherName` | Direct map when present; fall back to `"Microsoft"`. | mapped |
      | `Region` | `ResourceLocation` | Direct map. | mapped |
      | `ServiceCategory` | `ServiceFamily` | Map ServiceFamily to FOCUS ServiceCategory (see note below). | derived |
      | `ServiceName` | `ConsumedService` | Direct map. | mapped |
      | `SkuId` | `MeterId` | Direct map. | mapped |
      | `SkuPriceId` | `PartNumber` | Direct map when present. | mapped |
      | `SubAccountId` | `SubscriptionId` | Direct map. | mapped |
      | `SubAccountName` | `SubscriptionName` | Direct map. | mapped |
      | `AvailabilityZone` | Not in standard export | null — Azure does not export AZ in Cost Management export by default. | null |
      | `ResourceId` | `ResourceId` | Direct map. | mapped |
      | `ResourceName` | `ResourceName` | Direct map. | mapped |
      | `ResourceType` | `ResourceType` | Direct map. | mapped |
      | `Tags` | `Tags` | Parse JSON tag string into key-value map. | derived |
      
      ### Azure ServiceFamily to FOCUS ServiceCategory
      
      | Azure ServiceFamily | FOCUS ServiceCategory |
      |---|---|
      | Compute | Compute |
      | Containers | Containers |
      | Storage | Storage |
      | Databases | Databases |
      | Networking | Networking |
      | AI + Machine Learning | AI and Machine Learning |
      | Analytics | Analytics |
      | Security | Security |
      | Identity | Identity |
      | Integration | Integration |
      | Developer Tools | Developer Tools |
      | Management and Governance | Management and Governance |
      | Other | Other |
      
      ---
      
      ## GCP Billing Export (BigQuery) → FOCUS v1.2
      
      GCP Billing Export uses nested/repeated fields in BigQuery. The table below uses dot notation for nested fields.
      
      | FOCUS column | GCP Billing Export field(s) | Transformation | Provenance |
      |---|---|---|---|
      | `BilledCost` | `cost` + sum of applicable `credits[].amount` | Add credit amounts (negative values) to cost. | derived |
      | `BilledCurrency` | `currency` | Direct map. | mapped |
      | `BillingAccountId` | `billing_account_id` | Direct map. | mapped |
      | `BillingAccountName` | Not in standard export | null — account name not included. | null |
      | `BillingPeriodStart` | `invoice.month` | Parse YYYYMM as first day of month UTC. | derived |
      | `BillingPeriodEnd` | `invoice.month` | Parse YYYYMM as first day of next month UTC. | derived |
      | `ChargeCategory` | `cost_type` | Map: `regular` → `Usage`; `tax` → `Tax`; `adjustment` → `Adjustment`; `rounding_error` → `Adjustment`. | derived |
      | `ChargeDescription` | `sku.description` | Direct map. | mapped |
      | `ChargeFrequency` | `cost_type` | `regular` → `Usage-based`; `tax` → `One-time`. | derived |
      | `ChargePeriodStart` | `usage_start_time` | Convert to ISO 8601 UTC. | derived |
      | `ChargePeriodEnd` | `usage_end_time` | Convert to ISO 8601 UTC. | derived |
      | `ConsumedQuantity` | `usage.amount` | Direct map. | mapped |
      | `ConsumedUnit` | `usage.unit` | Direct map. | mapped |
      | `EffectiveCost` | `cost` | GCP exports net cost after credits applied; same as BilledCost in most cases. | mapped |
      | `InvoiceIssuerName` | Static: `"Google"` | Fixed value. | derived |
      | `ListCost` | `cost_at_list` (if present in resource-level export) | Direct map when available; null otherwise. | mapped |
      | `ListUnitPrice` | Not in standard export | null — not available in standard BigQuery export. | null |
      | `PricingCategory` | `credits[].type` | If credits include `COMMITTED_USAGE_DISCOUNT`: `Committed`; else `Standard`. | derived |
      | `PricingQuantity` | `usage.amount_in_pricing_units` | Direct map. | mapped |
      | `PricingUnit` | `usage.pricing_unit` | Direct map. | mapped |
      | `ProviderName` | Static: `"Google Cloud"` | Fixed value. | derived |
      | `PublisherName` | Static: `"Google Cloud"` | Fixed value. | derived |
      | `Region` | `location.region` | Direct map. | mapped |
      | `ServiceCategory` | `service.description` | Map service name to FOCUS ServiceCategory (see note below). | derived |
      | `ServiceName` | `service.description` | Direct map. | mapped |
      | `SkuId` | `sku.id` | Direct map. | mapped |
      | `SkuPriceId` | Not in standard export | null — not available. | null |
      | `SubAccountId` | `project.id` | Direct map. | mapped |
      | `SubAccountName` | `project.name` | Direct map. | mapped |
      | `AvailabilityZone` | `location.zone` | Direct map. | mapped |
      | `ResourceId` | `resource.name` | Direct map when present. | mapped |
      | `ResourceName` | `resource.global_name` | Direct map when present. | mapped |
      | `ResourceType` | Not in standard export | null — not available in standard export. | null |
      | `Tags` | `labels` (repeated key-value) | Flatten repeated label records into key-value map. | derived |
      
      ---
      
      ## OCI Billing → FOCUS v1.2
      
      OCI provides billing data through the Cost and Usage Reports (CSV export) and the Usage API.
      
      | FOCUS column | OCI column(s) | Transformation | Provenance |
      |---|---|---|---|
      | `BilledCost` | `cost/myCost` | Direct map. | mapped |
      | `BilledCurrency` | `currency/currencyCode` | Direct map. | mapped |
      | `BillingAccountId` | `product/tenancyId` | Direct map (tenancy OCID). | mapped |
      | `BillingAccountName` | Not in standard export | null — tenancy name not in CSV export. | null |
      | `BillingPeriodStart` | `lineItem/intervalUsageStart` | Convert to ISO 8601 UTC (first day of month for monthly export). | derived |
      | `BillingPeriodEnd` | `lineItem/intervalUsageEnd` | Convert to ISO 8601 UTC. | derived |
      | `ChargeCategory` | `lineItem/lineItemType` | Map: `USAGE` → `Usage`; `CREDIT` → `Credit`; `TAX` → `Tax`. | derived |
      | `ChargeDescription` | `product/resourceName` + `product/serviceName` | Concatenate service and resource name. | derived |
      | `ChargeFrequency` | `lineItem/lineItemType` | `USAGE` → `Usage-based`; `CREDIT` → `One-time`. | derived |
      | `ChargePeriodStart` | `lineItem/intervalUsageStart` | Convert to ISO 8601 UTC. | derived |
      | `ChargePeriodEnd` | `lineItem/intervalUsageEnd` | Convert to ISO 8601 UTC. | derived |
      | `ConsumedQuantity` | `usage/consumedQuantity` | Direct map. | mapped |
      | `ConsumedUnit` | `usage/consumedQuantityUnits` | Direct map. | mapped |
      | `EffectiveCost` | `cost/myCost` | Same as BilledCost for OCI standard export. | mapped |
      | `InvoiceIssuerName` | Static: `"Oracle"` | Fixed value. | derived |
      | `ListCost` | `cost/unitPrice` × `usage/consumedQuantity` | Compute from unit price and quantity when both present. | derived |
      | `ListUnitPrice` | `cost/unitPrice` | Direct map. | mapped |
      | `PricingCategory` | Not in standard export | Default to `Standard` unless commitment discount indicators present. | assumed |
      | `PricingQuantity` | `usage/billedQuantity` | Direct map when present. | mapped |
      | `PricingUnit` | `usage/billedQuantityOverageUnits` or `usage/consumedQuantityUnits` | Use billed quantity unit when present; fall back to consumed unit. | derived |
      | `ProviderName` | Static: `"Oracle Cloud Infrastructure"` | Fixed value. | derived |
      | `PublisherName` | Static: `"Oracle"` | Fixed value. | derived |
      | `Region` | `product/region` | Direct map. | mapped |
      | `ServiceCategory` | `product/service` | Map OCI service name to FOCUS ServiceCategory (see note below). | derived |
      | `ServiceName` | `product/serviceName` | Direct map. | mapped |
      | `SkuId` | `product/skuPartNumber` | Direct map. | mapped |
      | `SkuPriceId` | Not in standard export | null — not available. | null |
      | `SubAccountId` | `product/compartmentId` | Direct map (compartment OCID). | mapped |
      | `SubAccountName` | `product/compartmentName` | Direct map. | mapped |
      | `AvailabilityZone` | `product/availabilityDomain` | Direct map. | mapped |
      | `ResourceId` | `product/resourceId` | Direct map when present. | mapped |
      | `ResourceName` | `product/resourceName` | Direct map. | mapped |
      | `ResourceType` | Not in standard export | null — not in OCI cost export. | null |
      | `Tags` | `tags/<key>` columns | Flatten tag columns (prefix `tags/`) into key-value map. | derived |
      
      ### OCI service to FOCUS ServiceCategory
      
      | OCI product/service | FOCUS ServiceCategory |
      |---|---|
      | Compute | Compute |
      | Container Engine for Kubernetes | Containers |
      | Object Storage | Storage |
      | Block Storage | Storage |
      | Database | Databases |
      | MySQL | Databases |
      | NoSQL | Databases |
      | Networking | Networking |
      | Load Balancing | Networking |
      | Generative AI | AI and Machine Learning |
      | Data Science | AI and Machine Learning |
      | Data Flow | Analytics |
      | Other | Other |
      
  • metadata.json 1 KB
    {
      "id": "focus-spec-normalizer",
      "name": "FOCUS Spec Normalizer",
      "type": "skill",
      "provider": "multi-cloud",
      "harnesses": [
        "codex",
        "claude-code",
        "cursor",
        "gemini",
        "kiro",
        "other"
      ],
      "summary": "Normalize vendor-specific billing rows from AWS CUR, Azure Cost Management, GCP Billing Export, and OCI into FOCUS v1.2 columns. Operates on user-pasted CSV or JSON input. Refuses to invent column values not derivable from the input. No credentials accepted.",
      "source_type": "original",
      "official_docs": [
        "https://focus.finops.org/",
        "https://focus.finops.org/the-current-release/"
      ],
      "security_notes": "No cloud credentials, billing account IDs, tenant IDs, or service principal data are accepted or required. The skill operates on user-pasted de-identified billing data only. No live cloud API connections are made.",
      "last_verified": "2026-05-13",
      "path": "skills/finops/focus-spec-normalizer",
      "author": "github: VincentChuWaiChow",
      "version": "0.1.1",
      "lifecycle": "experimental"
    }
    
  • README.md 1.5 KB
    # FOCUS Spec Normalizer
    
    A FinOps skill that normalizes vendor-specific billing rows into FOCUS v1.2 columns from user-pasted CSV or JSON input. Operates on caller-supplied data only; refuses to invent values not present in the input.
    
    ## Purpose
    
    Map billing rows from AWS Cost and Usage Report (CUR), Azure Cost Management export, GCP Billing Export, or OCI billing into the FinOps Open Cost and Usage Specification (FOCUS) v1.2 column schema. Each output column is annotated with a provenance label (mapped, derived, or null) and gaps are documented with resolution notes.
    
    ## Allowed tools
    
    `Read` `Grep` `Glob`
    
    ## Usage
    
    **Single row:** Paste one billing row as CSV (with header) or JSON object. The skill detects the vendor from the column names, applies the appropriate mapping, and returns a FOCUS v1.2 JSON object with per-column provenance labels and a gap summary.
    
    **Multi-row batch:** Paste multiple rows (CSV table or JSON array). The skill maps each row and returns an array of FOCUS objects plus an aggregate gap summary covering all rows.
    
    ## Trust posture
    
    Read-only. No cloud credentials, billing account IDs, tenant IDs, or tenant-specific data accepted. All input is user-provided; no live cloud API connections are made. The skill will not invent, default, or infer values for FOCUS columns that are absent from the input — absent columns are set to `null` with a stated reason.
    
    Targets FOCUS v1.2. The FOCUS version is declared in every output.
    
    See [SKILL.md](SKILL.md) for the full mapping behavior, vendor detection logic, and response shape.
    
  • SKILL.md 4.8 KB
    ---
    name: focus-spec-normalizer
    description: Normalize vendor-specific billing rows (AWS CUR, Azure Cost Management, GCP Billing Export, OCI) into FOCUS v1.2 columns from user-pasted CSV or JSON input. Refuses to invent column values not derivable from the input. No credentials accepted; operates on user-supplied data only.
    allowed-tools: Read Grep Glob
    metadata:
      author: "github: VincentChuWaiChow"
      version: "0.1.1"
      updated: "2026-05-13"
      category: finops
      lifecycle: experimental
    ---
    
    # FOCUS Spec Normalizer
    
    ## Purpose
    
    Map vendor-specific billing row data (pasted as CSV or JSON snippet) to FOCUS v1.2 columns. The output is a FOCUS-normalized row or set of rows that can be ingested by any FinOps tool that accepts FOCUS-formatted data.
    
    No network access. No credentials. All input is user-supplied billing data.
    
    ## When to use
    
    Use this skill when:
    
    - The user has pasted one or more billing rows from AWS CUR, Azure Cost Management export, GCP Billing Export, or OCI billing and wants them mapped to FOCUS v1.2 columns
    - The user wants to understand which FOCUS columns can and cannot be populated from a given vendor's billing format
    - The user is building a multi-cloud cost normalization pipeline and needs the column-level mapping documented
    
    ## Operating rules
    
    - **No credential accepted.** No cloud credentials, billing account IDs, tenant IDs, or service principal data are accepted. The user pastes de-identified or sample billing data; no live API connection is made.
    - **No invented values.** If a FOCUS column cannot be populated from the data in the input row, the output cell is set to `null` and the reason is stated. Do not infer, default, or fabricate values for required FOCUS columns that are absent from the input.
    - **Input format.** Accept CSV (with header row) or JSON object/array. State the detected format before mapping.
    - **Provenance labels.** Every mapped FOCUS column value must carry one label:
      - `mapped` — value is directly present in the input row under a different column name
      - `derived` — value is computed from one or more input columns using a documented transformation (state the transformation)
      - `null` — column cannot be populated from the available input (state why)
    - **FOCUS version.** This skill targets FOCUS v1.2. State the FOCUS version in every output.
    - **Load references only when needed.**
    
    ## Mapping behavior
    
    ### Step 1: detect vendor
    
    Identify the billing format from the column names present in the input header:
    - AWS CUR: columns include `lineItem/UsageType`, `lineItem/ProductCode`, `lineItem/BlendedCost`, `lineItem/UnblendedCost`
    - Azure Cost Management: columns include `CostInBillingCurrency`, `ResourceType`, `SubscriptionId`, `MeterName`
    - GCP Billing Export: columns include `service.description`, `sku.description`, `cost`, `usage.amount`, `project.id`
    - OCI: columns include `currency/currencyCode`, `cost/myCost`, `service/serviceName`, `product/resourceName`
    
    If the vendor cannot be identified from column names, ask one clarifying question.
    
    ### Step 2: apply vendor-specific mapping
    
    Load the relevant mapping section from references/vendor-mapping.md for the detected vendor, then produce FOCUS v1.2 output columns.
    
    ### Step 3: flag gaps
    
    For any required FOCUS v1.2 column that cannot be populated, include a gap note:
    
    ```
    <FocusColumn>: null
      Reason: <why this column cannot be populated from <vendor> billing data>
      Resolution: <where in the vendor's billing config this data can be enabled, if known>
    ```
    
    ## Response shape
    
    Return:
    
    1. Detected vendor and input format.
    2. FOCUS v1.2 normalized row(s) in JSON object format.
    3. Provenance label for each column value.
    4. Gap summary table listing columns set to null and resolution notes.
    5. FOCUS version declared: `1.2`.
    
    Example output structure:
    
    ```json
    {
      "FocusVersion": "1.2",
      "ProviderName": "Amazon Web Services",
      "PublisherName": "Amazon Web Services",
      "ServiceCategory": "Compute",
      "ServiceName": "Amazon EC2",
      "ChargeCategory": "Usage",
      "ChargeDescription": "...",
      "ChargeFrequency": "Usage-based",
      "BillingPeriodStart": "2026-04-01T00:00:00Z",
      "BillingPeriodEnd": "2026-05-01T00:00:00Z",
      "BilledCost": 42.50,
      "BilledCurrency": "USD",
      "EffectiveCost": null,
      "ListCost": null,
      "ContractedCost": null,
      "ResourceId": "i-0abc1234def567890",
      "ResourceName": null,
      "SkuId": "RunInstances:0014",
      "SkuPriceId": null,
      "Region": "us-east-1",
      "AvailabilityZone": "us-east-1a",
      "Tags": {}
    }
    ```
    
    Each field in the output is annotated with its provenance label in the gap summary.
    
    ## References
    
    Load these only when needed:
    
    - [FOCUS v1.2 column definitions](references/focus-columns.md) — every required column with type and example.
    - [Vendor mapping tables](references/vendor-mapping.md) — AWS CUR, Azure Cost Management, GCP Billing Export, and OCI to FOCUS mapping.
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related