Breaking changes
Unreleased - brand-neutral technical contracts
This release keeps the Vluna name at distribution, SDK, and integration
boundaries while removing it from domain and protocol contracts. Package names,
service domains, VLUNA_* environment variables, the vlunactl binary, and the
vluna.* MCP tool namespace are unchanged. There are no legacy aliases or dual
reads for the renamed identifiers below.
Browser return parameters
vluna_checkout_id->billing_checkout_idvluna_checkout_result->billing_checkout_resultvluna_subscription_id->billing_subscription_idvluna_subscription_management_result->billing_subscription_management_result
Applications must update return URL handling atomically with the service deploy. Checkout and subscription-management URLs signed by the previous build are no longer valid because their signing domains changed.
Payment-provider metadata
Provider-owned correlation data now uses billing-domain names:
vluna_realm_id->billing_realm_idvluna_catalog_product_id->billing_catalog_product_idvluna_catalog_price_id->billing_catalog_price_idvluna_checkout_id->billing_checkout_idvluna_context->billing_checkout_contextvluna_operation_id->billing_operation_idvluna_change_policy->billing_change_policyvluna_anchor_policy->billing_anchor_policyvluna_scheduled_plan_change->billing_scheduled_plan_changevluna_keep_current_anchor->billing_keep_current_anchorvluna_billing_account_id->billing_account_idvluna_principal_id->principal_idvluna_billing_invoice_id->billing_invoice_idvluna_invoice_number->invoice_numbervluna_billing_invoice_line_id->billing_invoice_line_idvluna_billing_invoice_adjustment_id->billing_invoice_adjustment_id
Existing Stripe or Paddle objects carrying the old keys are not discovered by the new build. Reset development provider data, or migrate provider metadata before deployment; otherwise catalog bootstrap can create parallel objects and provider-operation replay detection can miss earlier mutations.
API schemas, Cloud identifiers, and SDK boundaries
- Contract pricing terms now require
schema=billing/contract_pricing:v2. Existing development terms must be replaced. - Cloud catalog bootstrap identifiers changed from
vluna_cloud_*plan and bundle keys tocloud_*, fromvluna-cloud-plantocloud-plan, fromvluna.gated_eventstoplatform.gated_events, and fromsource=vluna_pricing_pagetosource=pricing_page. - The Cloud pricing seed file is now
0002_seed_cloud_pricing.yamlinstead of0002_seed_vluna_cloud_pricing.yaml.
SDK package and integration identities remain branded and are not part of this technical-contract rename:
- TypeScript retains
VlunaAIServiceClient,VlunaAIBearerClient,VlunaAIConfig, andVlunaAIError. - Python retains
VlunaAIConfigandVlunaAIError; itsServiceClientandBearerClientclass names remain unchanged. - Adapter templates retain branded config, plugin, logger, context, and sentinel identifiers.
- The Web console keeps the
vluna.dev.s2s_credentiallocal-storage namespace.
Regenerate clients from the current OpenAPI documents. Existing Cloud bootstrap data must also be reset or migrated before applying the renamed seed identifiers.
The first-party Web console now consumes the renamed callback parameters while continuing to use the branded SDK symbols.
Runtime identifiers
VLUNA_PLANEremains the configuration variable, but its OSS/Enterprise default value is nowruntimeinstead ofvluna.- Migration session settings are now
app.runtime_schema,app.runtime_password, andapp.runtime_role. - Platform tokens with legacy
token_use=vlunaare rejected. Reissue legacy tokens;platform,plt, andaptremain the recognized token-use values. - The legacy
apttoken derivation salt changed to the neutralapt-tokendomain, so previously issuedapttokens must also be reissued. - Non-production DAT and MCP fallback signing seeds changed; restart local clients and issue new development session tokens after upgrading.
Unreleased - exact rational rating and caller-owned runtime references
This release is intentionally destructive. It does not accept legacy Gate or meter-price fields, and it does not migrate legacy pricing, residual, lease, or Budget-reference data. Rebuild affected development data and regenerate clients from the current OpenAPI documents.
Meter prices and rating
- Meter revenue is now the exact rate
unit_price_xusd / unit_quantity_minor; provider cost isunit_cost_xusd / cost_unit_quantity_minor. Both complete pairs are required. unit_quantity_minorandcost_unit_quantity_minorare quote/reference quantities and mathematical divisors, not billing blocks.- Per-line rounding modes and legacy residual-bucket behavior were removed.
Rating uses
integer_rational_floor_v1with remainder state separated by billing user, meter, pricing kind, and resolved rate identity. - Meter-price
effective_atis server managed. A no-op round trip preserves it; a material rate change advances it. Clients cannot choose it. - Gate commit lines are discriminated by
rating_status. Ops rated records userating_algorithm/cost_rating_algorithmplus nullable rate fields. Both surfaces expose explicit missing snapshots instead of synthetic zero rates. client_unit_price_xusdis no longer accepted on Gate meter lines. Useclient_pricing_etagwhen sending an advisory client expectation.CurrencyAmountsguarantees onlyxusdas a named property. Other currency codes, includingusd, are dynamic keys.
Required action: update meter-price writes with both exact rate pairs, remove
rounding/block assumptions, narrow Gate lines by rating_status, inspect Ops
rating algorithms before reading rate fields, and regenerate SDK/OpenAPI types.
Contract pricing v2
kind=pricing contract terms must use schema=billing/contract_pricing:v2 and
exact rational fixed, multiplier, or delta adjustments. The embedded
meter_code must equal term_key; arbitrary legacy pricing JSON is rejected
with 422.
Required action: replace old contract pricing values instead of migrating them.
Gate leases
- Public Gate authorization credentials and IDs were replaced by the single
opaque
leasereference. - Authorize accepts optional caller-owned
lease; when omitted, it generates the reference returned to commit. - Gate authorization has no separate cleanup operation. Authorize reserves no funds, quota, or other consumable resource, so failed work needs no compensation request.
- Internal lease UUIDs remain an implementation detail.
Required action: pass lease from authorize to commit, or choose a unique
one-time operation reference yourself. If work fails or produces no usage,
finish without another Gate request; do not store public generated credentials.
Budget references
- Budget creation accepts optional caller-owned
budgetand returns bothbudget_idandbudget. - Authorize and direct ingest select a Budget with
budget; legacy Gatebudget_idinput is rejected. - Budget management endpoints and operational responses continue to use
budget_idwhere an internal ID is appropriate.
Required action: choose and carry an external budget reference in runtime
flows, or use the generated value returned by Budget creation. Do not rename
management URL parameters.
Entitlement diagnostics and default assignment
ENTITLEMENT.REQUIREDandENTITLEMENT.DENIEDerror envelopes include the rejected resource inmeta.- New and reactivated billing users must receive the realm's active default
plan assignment in the provisioning transaction. A missing/inactive default
plan fails provisioning with
SERVER.CONFIGrather than leaving a partial user.