Skip to content

fix(reporting): make currency obligation-scoped for multi-account producers #1171

Description

@bokelley

Summary

Reliable Reporting currently takes one process-wide ProducerOfferings.currency (default "USD") and copies it into every ReportingSourceSliceRequestV1. A multi-account producer cannot truthfully run accounts, media buys, or immutable report definitions in different currencies through one producer.

Currency is part of reporting correctness: the source contract validates it, monetary control-total units must agree with the pinned report definition, and consumers have a specific currency_mismatch status. It therefore must be resolved and frozen at the same durable scope as the obligation/revision, not supplied as mutable process configuration.

Desired SDK contract

Provide an SDK-owned resolution seam and durable representation. For example:

CurrencyResolver = Callable[
    [ReportingConfiguration, ReportingObligationRecord],
    Awaitable[str] | str,
]

ReportingProducer(..., currency_resolver=...)

The exact API can instead derive currency from an immutable report-definition binding. The important invariants are:

  1. resolve from trusted account/configuration/report-definition state;
  2. freeze the ISO 4217 code before source work starts;
  3. persist enough information that retries, restatements, status checks, and audits cannot change currency later;
  4. reject or deterministically partition mixed-currency scopes rather than aggregating incompatible money.

The existing fixed currency= option can remain as a convenient single-currency resolver/default, but it should not be the only supported shape.

Acceptance criteria

  • One producer can concurrently publish an EUR account and a USD account without separate processes or mutable global state.
  • Currency is derived from trusted, immutable configuration/definition/account data—not buyer context or a transient adapter response.
  • The resolved currency is frozen durably before acquisition and is stable across retry, restart, correction, and official restatement.
  • The SDK validates three-letter uppercase currency codes and ensures monetary rows/control totals agree with the pinned definition.
  • Mixed-currency obligations fail explicitly or are partitioned before aggregation; they are never silently coerced to USD.
  • Source request/manifest conformance and consumer currency_mismatch checks remain end-to-end testable.
  • Fixtures and documentation include a non-USD, multi-account example.

Adopter impact

Embedded Sales Agent supports tenant/account currencies and GAM-backed buys. Hardcoding USD would produce incorrect evidence and potentially incorrect billing reconciliation for non-USD clients, so it blocks a trustworthy rollout.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions