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.

The evidence drawer keeps a disputed chargeback from ever being a black box. It opens from any attribution surface, including Attribution (Cost / Attribution) and the Invocation feed (Quality / Invocation feed). Overrides and their review trail are listed under Overrides (Security & Compliance / Overrides).

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 reconciliation), stage_b (trained edge-existence 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 to 1, capped at 0.95) and its band: Chargeback-ready (coper >= 0.80), Provisional (0.50 <= coper < 0.80), or Estimated (coper < 0.50).
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 and the hash of the model artifact that produced the result, linked to its tracked record.
Result source For Stage B inference, whether a trained model or the heuristic baseline produced the answer. A fallback keeps this marker even when its coper is 0.80 or higher. Stage origin and evidence basis identify deterministic Stage A results.
Degradation state Whether the result was produced normally or under a degraded condition, such as the Stage B heuristic-baseline fallback.
Demotion reason If a previously chargeback-ready result was capped below the floor, why: calibration drift or model age.
Freshness The time the underlying data was current as of.
Export eligibility Whether this result is chargeback-ready (coper >= 0.80). A heuristic-baseline or degraded result stays out of chargeback, even at coper >= 0.80, until the same edge is re-observed under trained-model attribution: see Result source and what a chargeback includes.

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 Stage C allocated lines are confidence-capped at 0.70 where proportional allocation signals are present, and at 0.50 where the split rests on no such signal. The drawer states which ceiling applied, 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

Any user with view access to a result can open a dispute directly from its evidence drawer; opening a dispute never mutates the attribution. 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:

An open dispute is assigned, then moves under review. Review ends with a committed override, acceptance of the provisional attribution, or closure as duplicate or invalid. Resolving a dispute explains which outcome changes attribution.

  • 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 that applied to the line 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 an Engineer within scope or by an Admin, and approved by a separate Admin; 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 separate Admin approves 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. Enforcement is server-side and fail-closed, as described in roles & access control.

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 append-only 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 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 (a user your organization has authorized to place and release legal holds, whose authority is checked fail-closed on every lock and release) can lock an override (or every object scoped to a subject or case) for audit or legal hold. Placing or releasing a hold requires a fresh step-up assertion. 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.

A lock in the app is separate from the storage retention that protects the audit trail itself. Audit entries are append-only: no product surface or API edits or deletes one. The audit stream is written to object storage under S3 Object Lock in Governance mode with a 5-year retention period by default. In Governance mode, only a principal that holds the s3:BypassGovernanceRetention permission and sends the explicit bypass request header can shorten or remove retention before it expires. Venturi’s writer and retrieval roles never hold that permission. Withhold it from routine roles in the account that holds the bucket, and enable CloudTrail S3 data events on the bucket so that any bypass is recorded. Compliance mode, in which no user (including the account root user) can delete an object or shorten its retention before expiry, is configured at onboarding for deployments that require it. See audit-log immutability.

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; a dispute never changes attribution
Resolve a dispute by accept / close The dispute’s assignee, or an Admin
Propose an override An Engineer within scope, or an Admin
Approve an override An Admin who did not propose it; above the configured spend threshold, two approvers, neither of them the proposer
Lock or place a legal hold An Admin or a legal-gated actor, with a fresh step-up assertion; a tenant-wide hold requires two actors

Viewer and Auditor grants are read-only: they cannot resolve a dispute, propose or approve an override, or place a lock or legal hold. See roles & access control and the role & permission matrix for the full model.

Next steps

  • Use Coverage & unknowns to resolve the unknowns that disputes often start from.
  • Use Confidence and evidence to learn what the scores, states, and evidence basis mean.
  • Use The attribution pipeline to see the three stages whose decisions the drawer records, including RAIL (Resource Attribution & Inference Layer) inference in Stage B.
  • Use Audit logs to find where every override and resolution is recorded in the append-only audit trail.
Give feedback on this page

Sign in to send feedback. Opens in a new tab.

Copy page details
Docs feedback: Attribution detail
Page: https://docs.venturi.systems/dashboard/attribution-detail/