Skip to content

Attribution detail

Every number in Venturi is defensible because you can open it. Behind any attribution — a chargeback line, a team rollup, a single invocation — is an evidence drawer that shows exactly how Venturi reached that conclusion. When you disagree, you open a dispute; when the answer is genuinely wrong, you propose an audited override. This page explains all three.

This is the surface that makes a disputed chargeback never a black box.

The evidence drawer

From any attribution surface — a table row, a drill-down leaf, an export line you clicked through — open the evidence drawer to see the complete decision record for that result. It is the same record everywhere: the team rollup, the dispute, and the override all read from one source of truth.

The drawer shows:

Field What it tells you
Event The invocation (event_id) and what was called — provider, served model, tokens, cost, timestamp.
Resolved owner The team, project, identity, organization, and budget this invocation attributes to.
Stage origin Which stage produced the result: stage_a (deterministic), stage_b (trained inference), or stage_c (allocation).
Output state One of the six states — deterministically_resolved, strongly_inferred, bounded, ambiguous, unknown, not_identifiable.
Confidence The coper score (0–0.95) and its band.
Evidence basis The signals that supported the attribution — e.g. direct account binding, HRIS membership, deployment metadata, code ownership, telemetry correlation.
Candidate set Where more than one owner was plausible, every candidate with its supporting evidence — Venturi preserves the disagreement rather than hiding it.
Selection rationale Why the chosen owner won over the others.
Model version When inference was involved, the trained model version that produced the result, linked to its tracked record.
Degradation state Whether the result was produced normally or by a fail-open fallback.
Freshness The time the underlying data was current as of.
Export eligibility Whether this result is chargeback-ready (coper ≥ 0.80).

Drilling down never loses the evidence

Drill from an organization total → team → service → invocation and the interpretation metadata travels with you at every level. The leaf shows the exact same decision record the dispute and override surfaces use — there is no point where a number loses its provenance.

Reading a contested attribution

When the output state is ambiguous, bounded, or carries a conflict, the drawer shows the full candidate set side by side: each plausible owner, the evidence that supports it, and what would have to change for Venturi to resolve it. This is how you tell real ambiguity (a genuinely shared API key) from a fixable data-quality gap (stale org data, an unmapped identity, conflicting CI/CD metadata). For unknowns, see coverage & unknowns.

Reading an allocated (shared-service) line

Shared-service spend — a platform team's gateway, a common API key, a workload no single owner clearly drives — resolves through allocation rather than to a single point owner. For these stage_c lines the drawer shows you the allocation basis, not just the headline owner:

Field What it tells you
Fractional split The full N-way split across owners, with each owner's share. You see the whole distribution, not just the largest slice.
Producing signal class The class of signal the split was computed from — e.g. proportional usage, headcount, deployment footprint — so you know what the shares are based on.
Allocation ceiling Allocated and network-derived lines are confidence-capped at 0.70. The drawer states this plainly so you never read an allocated share as point-level certainty.

Because the split is visible, you can contest the share itself — the fraction assigned to a given owner — separately from contesting which owner is largest. The two are different challenges, and the drawer keeps them distinct: you can accept that the platform team is the primary consumer yet still argue their 60% should be 45%.

No prompt or completion content

The drawer shows the metadata and evidence behind an attribution — never prompt or completion text. Venturi never stores message content, so it is never in the drawer.

Disputes

A dispute is the collaborative way to challenge an attribution without ever changing it by accident. Disputes are a first-class object: assignable, commentable, SLA-tracked, and bound to the attribution they question — but they never mutate it.

A dispute never changes attribution truth

Comments, mentions, assignments, and the dispute thread itself are metadata about an attribution. The attribution record — its owner, coper, output state, and stage origin — is byte-for-byte identical before and after a dispute. The only action that changes attribution is a committed override (below), and that change is an append, never a silent edit.

Opening a dispute

Anyone with view access to a result can open a dispute directly from its evidence drawer. The dispute is pre-populated with the event_id, the full candidate set, the output state, the coper, and the selection rationale, and is linked both ways to the attribution record.

If an open dispute already exists on the same event, entity, or candidate pair, Venturi offers to link to it rather than fork a duplicate — so two people investigating the same number converge instead of colliding.

Working a dispute

A dispute moves through a clear lifecycle, with collaboration at every step:

graph LR
  A[Open] --> B[Assigned]
  B --> C[Under review]
  C --> D{Resolve}
  D -->|Override committed| E[Resolved · override]
  D -->|Provisional accepted| F[Resolved · accepted]
  D -->|Duplicate / invalid| G[Closed]
  • Assign the dispute to a person or a role queue (for example, the FinOps review queue). Reassignment is audited and carries the SLA clock with it.
  • Comment in a threaded discussion visible only to users with view scope on the dispute. Comments are editable by their author within a window, then append-only.
  • Track the SLA — each dispute carries a configurable SLA clock that respects your business calendar; a breach raises an escalation exactly once, up the chain to the role queue and then to an admin until acknowledged.

The manual-review queue orders disputes by the canonical priority — highest spend first, then chargeback-eligible disputes, then highest uncertainty — so the work that matters most surfaces first.

Resolving a dispute

A dispute resolves one of three ways, and only one of them changes attribution:

Resolution What happens Changes attribution?
Commit an override A manual-override event is appended; the attribution is corrected. Yes — by append
Accept the provisional You accept Venturi's answer as-is. No
Close as duplicate / invalid The dispute is closed with a reference. No

Resolving via accept changes no graph edge. Resolving via override is the path described next. Both record the actor, timestamp, reason, and prior state.

Resolving non-point results

The hardest spend to attribute — bounded results where more than one owner is plausible, and stage_c allocated lines split across several owners — is also the spend you most need to defend internally. So a dispute on a non-point result gives you resolution paths that match the shape of the answer, not just an all-or-nothing accept:

  • Resolve a bounded result. When the output state is bounded, you can resolve the dispute to a specific candidate within the set — "it's this team" — or assert a fractional split across the bounded candidates — "60% this team, 40% that one." Either choice is recorded as a structured, append-only override and fed back as a strong supervision signal, so the engine learns your correction for next time.
  • Contest an allocated share. For a stage_c allocated line, you contest the split the drawer renders — the fraction assigned to an owner — on a path that is distinct from contesting which owner is largest. You can leave the primary consumer unchallenged and still correct the percentages, or challenge both. Either way the allocation ceiling of 0.70 still applies: an allocated line is never promoted to point-level confidence by a dispute.

Correct the share, not just the headline

A shared API key that splits 60/40 between two teams is a real, defensible number — but only if you can inspect and adjust the split. Venturi lets you contest the fraction itself, so the spend that is hardest to attribute is no longer the spend you can least defend.

Overrides

An override is the one human action that corrects an attribution — and it is designed to be permanent, auditable, and impossible to do unilaterally on high-stakes spend.

How an override is proposed and approved

An override is proposed by a user and approved by a separate person — separation of duties is enforced on the server and made visible in the UI:

You cannot approve your own override

The user who proposes an override can never be its sole approver. When the proposer opens the approval control, it is disabled with a clear explanation — "you proposed this; a separate approver is required" — rather than failing only at submit. A second principal with approval rights completes it. For overrides on large spend, a configurable threshold escalates from single-approver to dual-approver automatically. Rejection requires a reason code from an audited taxonomy.

What an override does — and how long it lasts

A committed override is an append-only correction. It is never an in-place edit:

  • It survives graph rebuilds. When attribution is recomputed, your override is re-applied — it is never silently reversed by the next run.
  • It is fully audited. Actor, approver, timestamp, reason code, and the prior state are written to the immutable audit log.
  • It can be revoked through the same audited, separated-duty workflow — which is itself another append, preserving the full history.

This is why a corrected number stays corrected, and why an auditor can always see both what the engine concluded and what a human changed, with the reason.

Seeing the effect of your override

The moment you commit an override, Venturi shows you an effect summary in the same session — so a correction never disappears into the audit log with nothing to show for it. You acted, and you immediately see what changed:

The summary tells you What it means
Attributions changed The count and total spend of currently-materialized attributions that moved as a direct result of your correction — so you can confirm your chargeback number is actually fixed.
Time-basis treatment Exactly how historical records were handled: whether they were re-attributed to the corrected owner or preserved at their original event-time owner. This is always stated explicitly — never silently chosen for you.
Captured for the future Confirmation that your correction was recorded as a governed signal the engine learns from, so the same misattribution does not recur.

The summary reports effects — it never rewrites history

The effect summary describes how your override flows through the currently-materialized view. It composes the same append-only, no-mutation guarantees as everything else on this page: prior states are preserved, the correction is an append, and the summary simply makes its reach visible. Seeing "47 attributions, $128k re-attributed" is how you know the fix landed — without it, a correct override would feel ignored.

An admin or a legal-gated actor can lock an override (or every object scoped to a subject or case) for audit or legal hold. A locked object rejects edits, archival, and deletion, and is excluded from retention purges until released. Lock and release are fail-closed, and tenant-wide holds require two actors.

Custom fields and templates

Admins can add typed custom fields (text, number, enum, date, or entity-reference) to disputes and overrides — for example a "BU code" enum — which then appear as search facets and export columns. Reusable intake templates (a standard dispute form, a standard override request) pre-populate new objects so your team captures the right context every time.

Who can do what

Action Who
Open and comment on a dispute Any user with view access to the attribution
Resolve a dispute by accept / close The dispute owner or an admin
Propose an override An engineer (or higher) within scope
Approve an override A separate admin (or threshold-required second approver)
Lock / legal-hold An admin or legal-gated actor

See roles & RBAC for the full matrix.

Next steps