Skip to content

The attribution graph

Everything Venturi knows about your AI consumption is stored as a graph: nodes for the things that exist in your environment, edges for the relationships between them. The attribution engine builds this graph, and every dashboard number, chargeback line, and budget alert is a query over it.

This page explains the layers of that graph so you can read an attribution and know exactly what each link means.

The six layers

Venturi links every AI invocation across six layers, from the individual request all the way up to the budget that pays for it:

graph TD
  I["1 · Invocation<br/>a single AI request"] --> S["2 · Service<br/>the app / workload"]
  I --> ID["4 · Identity<br/>the person / principal"]
  S --> P["3 · Project<br/>the code / repo"]
  S --> ID
  P --> O["5 · Organization<br/>team / org unit"]
  ID --> O
  O -. "BUDGETED_UNDER / BILLED_TO" .-> B["6 · Budget responsibility"]
Layer What it represents Example
1 · Invocation A single AI inference request. One call to a chat model, with its tokens, cost, and timestamp.
2 · Service The application or workload that made the request. checkout-api, support-copilot.
3 · Project The code, repository, or deployable unit behind the service. The repo that owns checkout-api.
4 · Identity The person or principal responsible for the request. An engineer, a service account, a CI pipeline.
5 · Organization The team or org unit the identity and project roll up to. Payments, Customer Support.
6 · Budget responsibility Who pays — the cost center or budget the spend is charged to. The Payments cost center.

Budget is an attribute, not a separate object

Under the hood, the graph has five node types — Invocation, Service, Identity, Organization, and Project. The sixth layer, budget responsibility, is an attribute of the Organization, expressed through the BUDGETED_UNDER and BILLED_TO edges rather than a standalone node. You can think and talk in six layers; the engine stores it as five nodes plus wire edges. The two views are exact equivalents.

Nodes: the things in your environment

The graph has exactly five node types, and they are fixed:

  • Invocation — one resolved AI request.
  • Service — a running workload.
  • Identity — a human or non-human principal.
  • Organization — a team or org-hierarchy unit.
  • Project — a code or deployment unit.

Venturi populates all five node types from your source data — gateway and proxy events, provider usage records, cloud billing, your identity directory (SSO / SCIM), and code-ownership signals such as CODEOWNERS — during Stage A of the pipeline.

Edges: the relationships Venturi resolves

Edges are where attribution actually happens. An edge is a claim that this invocation belongs to that service, this identity belongs to that organization, and so on. Venturi resolves these relationships:

Edge Meaning Typical evidence
invocation → service This request came from this workload. Gateway logs, OTel spans, pod metadata, log correlation.
invocation → identity This request was made by this principal. API key binding, auth context, account mapping.
invocation → project This request belongs to this codebase. Deployment metadata, service registry.
service → identity This service is operated by this principal. Ownership records, service accounts.
service → project This service is built from this code. CI/CD, deployment events, registries.
identity → organization This person belongs to this team. HRIS, IdP group membership, SCIM.
project → organization This code is owned by this team. CODEOWNERS, repo ownership.
identity → project This person contributes to this code. Commit / ownership history.

Each edge carries the attribution metadata that makes it actionable: an output state, an operational confidence score, the stage that resolved it, and the evidence behind it. When you click into an attribution on a dashboard, you are inspecting one or more of these edges.

Wire edges in the AttributionRecord

When the engine materializes its output as an AttributionRecord, the graph relationships are written as a set of stable wire edges that downstream systems consume: owns, member_of, deployed_in, called_by, produced_by, billed_to, owned_by_org, and budgeted_under. These are the relationships you see reflected in exports and the API — the durable, contract-stable form of the graph above.

Why a graph and not just tags

Tags break the moment ownership is shared, code is renamed, a team reorganizes, or someone forgets to apply them. A graph does not:

  • Shared resources resolve cleanly. A shared API key or endpoint becomes one invocation node linked to multiple candidate owners, and Stage C splits the cost fractionally rather than forcing a single wrong answer.
  • Reorganizations are absorbed. Because identity-to-organization is an edge resolved from your live directory, moving a person between teams updates attribution automatically.
  • Provenance is preserved. Every edge records how it was resolved, so a disputed chargeback line can be traced back to its evidence.

Where to go next