System architecture¶
This is the complete architecture of Venturi for customer architects: where the system runs, how it is partitioned into planes, how attribution is built, where your data lives, and, most importantly, where it does not. It is the reference to hand to whoever reviews Venturi before it goes into your environment.
If you only need to connect and start seeing attribution, start with the Quickstart. If you want the security-reviewer summary, read Trust & security. This page is the architecture underneath both.
The one-sentence model
Venturi is the system of record for AI. Attribution connects AI activity to accountable owners, connected workflows and systems, and customer-defined outcomes. It deploys as a data plane inside a dedicated single-tenant boundary, reads cost/usage/identity signals, correlates AI invocations to the team, service, identity, and budget responsible, and, by design, does not block your AI traffic (fail-open) and has no schema field for prompt or completion content.
Deployment model: dedicated data plane¶
Venturi runs as a dedicated, single-tenant data plane. Self-hosted mode places it in your VPC, project, or subscription. SaaS mode places the same logical plane in a Venturi-operated environment pinned to your contracted residency lane. Your operational data stays in that tenant boundary. The separate control plane delivers signed releases and configuration and never holds raw tenant data.
| Connection | Purpose |
|---|---|
| Decision-time interceptor → Event stream | Emit invocation metadata for asynchronous processing. |
| Event stream → Attribution processor | Consume events for attribution. |
| Attribution processor → Attribution graph | Store supported ownership relationships. |
| Attribution graph → Materialized index | Publish the view used for reads. |
| Materialized index → Dashboard / API | Serve attribution to your engineers and finance team. |
| Data plane → Venturi control plane | Pull signed releases and configuration through an outbound connection. |
Three product invariants follow from these boundaries:
- Your operational data stays in the dedicated tenant boundary. Venturi’s shared development, certification, and release-rehearsal environments do not hold customer operational data.
- Integrations are read-only. Venturi reads cost, usage, and identity. It never writes back into your environment. This is enforced, not promised: see Trust & security.
- The decision-time interceptor fails open. It never depends on an external control plane to let your traffic through.
Outbound-only data-plane fetches
The tenant data plane reaches out for signed release artifacts and configuration. There is no inbound path from Venturi’s control plane into your data. Server-initiated outbound calls to customer-named endpoints (billing hosts, connectors, webhooks) pass through a single hardened fetch wrapper with private/link-local/metadata-IP denial and DNS-rebind protection, so a connector can never be coerced to reach your instance-metadata service or internal hosts.
The three planes¶
Venturi partitions cleanly into three planes with different latency profiles, different failure semantics, and different responsibilities. Keeping them separate is what lets the synchronous path stay fast and fail open while the analytics path stays correct and durable.
The Interceptor row refers to the decision-time interceptor.
| Plane | Job |
|---|---|
| Interceptor | Observe live AI invocations at decision time |
| Attribution processor | Build the attribution graph and confidence |
| Dashboard / API | Serve attribution to people and systems |
| Plane | Path |
|---|---|
| Interceptor | Synchronous hot path |
| Attribution processor | Asynchronous, off the hot path |
| Dashboard / API | Synchronous read |
| Plane | Failure |
|---|---|
| Interceptor | Fails open: forwards your traffic, by design, when any Venturi dependency behind it fails |
| Attribution processor | Reconciles later; never on the request path |
| Dashboard / API | Fails closed: denies on auth/tenant error |
Decision-time interceptor plane (synchronous, fail-open)¶
The interceptor plane optionally sits in the decision-time path of an AI request. Its only job there is to observe: record that an invocation happened and what identity/service made it, and forward the request unmodified. It performs a fast index lookup, not inline model inference, and emits an event onto the stream for the processor plane to attribute asynchronously.
This plane works to a 50 ms P99 end-to-end latency budget, measured at the interceptor seam. Cooperative timeouts bound each internal step against a cumulative monotonic deadline. On an exception or timeout, the interceptor forwards the admitted request unmodified and records null attribution. The P99 budget is the latency objective across requests; it is not an externally enforced wall-clock guarantee for every individual request. Internal calls behind the interceptor (index lookup, policy evaluation) fit inside a 15 ms internal budget. Its only runtime dependencies are the fast in-memory index and the event stream: no graph database call ever enters the hot path, and no trained model runs there.
Fail-open for every admitted request
No Venturi dependency on the AI hot path may block your AI traffic. If a dependency behind the interceptor is slow, degraded, or down, the request is forwarded unmodified and attribution is reconciled later from the event. This is enforced by a cooperative timeout against a cumulative deadline. The one deliberate rejection is the drop-in proxy’s tenant admission, a security-relevant check that fails closed. See Fail-open vs fail-closed.
The decision-time interceptor is not the only way Venturi sees traffic. Venturi
classifies every AI pathway into one of the 20 classes of the governed
PathwayCategory taxonomy:
| Group | PathwayCategory classes |
|---|---|
| Direct and routed APIs | DIRECT_API, AI_GATEWAY, MODEL_ROUTER, BATCH_API |
| Cloud model platforms | AWS_BEDROCK, AZURE_OPENAI, VERTEX_AI, MANAGED_OTHER |
| Frameworks and agents | ORCHESTRATION_, AGENTIC_AI |
| Embedded SaaS | SAAS_, SAAS_ |
| Developer and workflow tools | DEVELOPER_TOOL, RPA_WORKFLOW |
| Self-hosted, edge, and client | SELF_HOSTED, EDGE_ON_DEVICE, CLIENT_SIDE_AI |
| Data platforms and model training | DATA_PLATFORM_AI, FINE_ |
| Unsanctioned use | SHADOW_AI |
It captures each pathway through whichever of six capture layers is feasible:
| Layer | Source |
|---|---|
| L1 | Network proxy / gateway |
| L2 | SDK / framework |
| L3 | Billing / control-plane |
| L4 | Observability pipelines |
| L5 | Source-of-record systems |
| L6 | Vendor admin APIs |
| Layer | Example |
|---|---|
| L1 | Live interceptor, AI gateway |
| L2 | Orchestration-framework instrumentation |
| L3 | CUR, BigQuery billing export, Cost Management |
| L4 | OpenTelemetry, metrics |
| L5 | HRIS, IdP, repository ownership |
| L6 | Provider usage/cost and audit-log APIs |
Each event carries a capture-feasibility class (FULLY_CAPTURABLE,
PARTIALLY_, INDIRECTLY_, or UNCAPTURABLE) so the system
states how much of a given pathway it can see; it never silently treats missing
visibility as zero.
Attribution processor plane (asynchronous)¶
The processor plane consumes the event stream and does the real work of attribution: running the three-stage attribution pipeline, building the attribution graph, computing calibrated confidence, and materializing results into the index that the dashboard reads. This is where 95%+ of attribution volume is handled, off the synchronous path. The asynchronous processor carries a 100 ms P99 Stage B budget, measured at the processor seam, and each Stage B call runs under a hard 20 ms wall-clock timeout inside that budget (see Stage B). Because it is asynchronous and event-sourced, it can take the time to be correct without ever touching your live traffic.
Dashboard / API plane (synchronous reads, fail-closed)¶
The dashboard and developer API serve attribution to your engineers, finance team, and systems. Reads are served from the materialized index at low latency. Every result carries its interpretation metadata (see Evidence on every result), so a number is never shown with more authority than its evidence supports. This plane is the fail-closed half of the system: authentication, authorization, tenant isolation, exports, and billing all deny on error.
The six-layer attribution graph¶
Venturi’s defensibility is the attribution graph: it correlates the AI inference signals it can see across six layers into one graph, designed to work without relying on manual tags. The layers and edges below match the canonical attribution graph page.
An invocation connects to its service and identity. A service connects to its
project and identity; projects and identities connect to organizations.
Organizations carry the budgeted_under and billed_to relationships that
express budget responsibility.
The six product layers are stored as five node types plus budget edges:
| Product layer | Graph node |
|---|---|
| Invocation | Invocation |
| Service | Service |
| Project | Project |
| Identity | Identity |
| Organization | Organization |
| Budget responsibility | (edges on Organization) |
| Product layer | Answers |
|---|---|
| Invocation | Which AI call happened? |
| Service | Which service or workload made it? |
| Project | Which codebase / project owns that service? |
| Identity | Which person or service account is responsible? |
| Organization | Which team / org unit do they roll up to? |
| Budget responsibility | Which cost center / budget is billed? |
Budget responsibility is an attribute of the organization expressed through
billed_to / budgeted_under edges, not a separate node. The graph uses a
frozen eight-edge wire taxonomy (owns, member_of, deployed_in, called_by,
produced_by, billed_to, owned_by_org, budgeted_under) so that every
relationship a result depends on is explicit and auditable.
The result answers the question finance and engineering both ask: which team, which service, which person, which budget is responsible for a given slice of AI spend, and it is designed to do so without relying on manual tags.
The three-stage attribution pipeline¶
Venturi’s attribution pipeline turns raw invocation signals into attributed,
confidence-scored records in three stages, each with its own owner. The Venturi
platform runs canonical ingress and Stage A deterministic resolution.
RAIL (Resource Attribution & Inference Layer) owns Stage B: it infers
the eligible ownership relationships that Stage A leaves unresolved and returns
an uncapped posterior confidence (cpost) with its evidence and alternatives.
RAIL’s research and training machinery supplies the verified Stage B models.
Stage C belongs to a separate allocation subsystem that splits genuinely
shared cost. Platform materialization applies the 0.95 operational-confidence
cap and publishes each AttributionRecord.
| Path | When it applies | Destination |
|---|---|---|
| Stage A → Platform materialization | Deterministic methods resolve the ownership edge. | Apply the operational-confidence cap and publish the record. |
| Stage A → Stage B → Platform materialization | An unresolved ownership edge is eligible for trained inference or its heuristic fallback. | Return cpost, evidence, and alternatives for materialization. |
| Stage A or Stage B → Stage C → Platform materialization | Cost is genuinely shared. | Allocate cost without changing ownership, then materialize. |
See the ownership paths for the focused interactive view. Allocation is a separate conditional path, rather than a mandatory step after inference.
Stage A: deterministic resolution (R1 to R5)¶
The platform’s Stage A resolves ownership from available evidence using five deterministic reconciliation methods:
| Method | Reconciliation signal |
|---|---|
| R1 | Direct key match (API key / service-account identifier) |
| R2 | Temporal proximity |
| R3 | Naming correlation |
| R4 | Historical patterns |
| R5 | Service-account trace |
Stage A is deterministic and machine-learning-free: the same input always
yields the same AttributionRecord fields, and no model runs in this stage.
Anything Stage A resolves carries stage_origin = stage_a and the strongest
confidence the evidence allows. This is the backbone of chargeback-grade
attribution.
Stage B: trained edge-existence inference¶
For the eligible edges Stage A cannot resolve deterministically, RAIL’s Stage B
asks a narrower question (does this edge exist?) and answers it with a trained attribution
model that runs inside the attribution processor, as described in the next
section. The model emits an uncapped posterior (cpost) per edge, which is
calibrated; platform materialization turns it into customer-facing confidence.
Each Stage B call has a hard 20 ms wall-clock timeout inside the asynchronous processor’s 100 ms P99 Stage B budget; Stage B never runs on the synchronous interceptor path. Stage B is wrapped in fallback behavior at every level. The processor answers an edge with a deterministic heuristic baseline instead of the trained model when any of these occurs:
- the call reaches its 20 ms timeout;
- the model artifact is missing;
- the model returns an invalid output;
- Stage B is disabled for that edge by flag;
- the call is shed because 8 calls are already in flight on that processor instance;
- the circuit breaker is open because the timeout rate exceeds its configured threshold (default: 5% over a 100-call rolling window);
- the edge’s readiness gate vetoes serving the trained model for that edge (a fail-closed, per-edge veto).
Separately, a canary rollout of a new model rolls back automatically, with no flag that can suppress it, if its expected calibration error (ECE) rises by more than 0.02. The heuristic baseline is a permanent safety feature that keeps attribution processing flowing. Stage B never makes a result fail; it only improves the attribution that the deterministic path already guarantees.
Stage C: fractional cost allocation¶
When an invocation genuinely cannot be pinned to a single owner, Stage C (a separate allocation subsystem outside RAIL) allocates its cost fractionally across the candidate owners using the R6 allocation prior. R6 carries explicit allocation semantics and a deliberate 0.50 ceiling on the prior itself. R6 is refused outright as evidence for whether an edge exists, not merely clamped, and the system is transparent that an allocation is an allocation, not a resolution. Allocated attribution lines carry their own operational-confidence ceiling: 0.70 where proportional allocation signals are present, and 0.50 where the split rests on no such signal. Both sit below the 0.80 chargeback floor, so an allocated line can be at most provisional, never chargeback-ready. (The numbers describe different things: 0.50 bounds the allocation prior itself; 0.70 and 0.50 bound the confidence of an allocated line.)
The output of the pipeline is the AttributionRecord: the durable, auditable
unit that carries the resolved edge, its output_state, its calibrated
confidence (coper), the originating stage, and the evidence behind it.
Six output states¶
Every result lands in exactly one of six output states; Venturi never fabricates a default when it does not know:
output_state |
Meaning |
|---|---|
deterministically_ |
Resolved by Stage A from deterministic evidence |
strongly_inferred |
High-confidence Stage B inference |
bounded |
Narrowed to a set; not a single owner |
ambiguous |
Multiple plausible owners remain |
unknown |
Insufficient evidence to attribute |
not_identifiable |
Cannot be attributed even in principle |
How Stage B is served¶
Stage B runs in-process inside the attribution processor, in your data plane. There is no separate inference service, no additional listener, and no network hop: the processor loads the model artifact into its own runtime, performs feature extraction and edge-existence inference within the 20 ms Stage B timeout, emits confidence and evidence semantics, and falls back to the deterministic heuristic baseline on any of the Stage B fallback conditions.
Model artifacts are delivered out of band rather than fetched on the request path or over the control-plane path. Before the processor starts, an init step stages them from object storage in the cloud account that hosts your data plane into the processor’s own storage, where they are mounted read-only and hash-verified before they are bound; verification failure refuses the artifact and the baseline answers instead. The models themselves are produced by Venturi’s internal research program and promoted through the human-gated process described below.
The seam is deliberately narrow. It is not a customer-facing app, a training UI, or an authorization boundary. It supplies evidence-backed predictions through one contract and owns nothing else: it does not own dashboards, billing, admin mutation, security controls, or exports.
What confidence means and how to act on it¶
Every attribution carries a single customer-facing confidence value, coper,
on a 0 to 1 scale. Two numbers govern how you use it:
| Threshold | Value | What it means |
|---|---|---|
| Confidence cap | 0.95 | The highest confidence Venturi ever asserts. This is a deliberate, conservative policy ceiling; Venturi never claims certainty on an inferred attribution. |
| Chargeback floor | 0.80 | An attribution must be at or above this to be eligible for internal chargeback and inclusion in a verified-savings calculation. |
So in practice: anything at 0.80 or above (Chargeback-ready) is solid
enough for internal chargeback, subject to reconciliation and degradation gates.
Below it, the attribution is Provisional
(0.50 <= coper < 0.80) or Estimated (coper < 0.50): use it for analysis and
investigate before acting. See
confidence bands.
Venturi caps inferred confidence at 0.95 by policy: when you see a number that
high, it means “as confident as we will ever assert,” not “certain.”
How the model is improved, and who decides
The production attribution model is selected and promoted by a human Venturi decision through a formal gate, never automatically. Promotion requires per-edge precision and calibration bars to clear, a non-waivable cap on high-confidence errors, and a canary rollout that auto-rolls-back without ever touching customer traffic if expected calibration error (ECE) rises by more than 0.02. The most explainable model wins ties. You consume the result of that discipline; you never have to operate it.
Evidence on every result¶
No attribution is presented as a bare number. Every customer-visible result carries interpretation metadata, so you can always see why and how strongly Venturi believes it. The evidence drawer shows this metadata; see evidence cards for how each item is presented:
stage_origin: Stage A deterministic, Stage B inference (trained model or heuristic baseline), or Stage C allocation.output_state: one of the six states above.coperand confidence band: the calibrated confidence and where it sits.evidence_basis: which reconciliation methods (R1 to R5) and which input evidence produced the result.model_versionandartifact_hash: the attribution-model version and the hash of the artifact that produced the result, where a model was involved.degradation_state: whether the result was produced normally or under a degraded condition. A Stage B result also carries a result-source marker (trained model or heuristic baseline), and an edge demoted below the chargeback floor records its demotion reason (calibration drift or model age).freshness: when the underlying data was last reconciled.
This metadata travels with the result everywhere it is shown: the same record backs the dashboard row, the evidence drawer, the dispute, and the export line. The absence of any required value is rendered explicitly as “unknown / unavailable,” never as a blank or a fabricated default: Venturi would rather tell you it does not know than guess.
Control plane vs data plane¶
| Aspect | Dedicated tenant data plane | Control plane (no inbound initiation) |
|---|---|---|
| Holds | Your events, graph, index, attribution records | Releases, configuration, licensing |
| Holds your data? | Yes, and only here | No |
| Direction | Internal to the self-hosted or SaaS tenant boundary | Data plane initiates outbound fetches only |
| Customer data egress | None | None |
Your data plane is the only place your operational data lives. The data plane fetches signed, verified release artifacts and configuration from the control plane; the control plane never reaches into your data. There is no path by which Venturi’s control plane reads your invocation events, your graph, or your index.
Fail-open vs fail-closed: the boundary¶
The single most important rule in the architecture is the fail-open boundary, and it is drawn precisely:
Fail-open applies to exactly one path
Fail-open applies only to customer AI traffic on the AI hot path. If a Venturi dependency behind the interceptor is slow, degraded, or unavailable, your AI request is forwarded unmodified and attribution is reconciled later. The one exception on this path is the drop-in proxy’s tenant admission, an authentication and tenant-isolation check that fails closed: a provider key that is not registered to your tenant is rejected before anything is forwarded. Fail-open cannot cover the drop-in proxy endpoint itself: a request pointed at the proxy reaches the provider only if it reaches the proxy. For workloads that cannot accept that dependency, see the failover guidance on Drop-in proxy.
Everything security-relevant fails closed
Fail-closed applies to every security-relevant decision: authentication, authorization (RBAC), tenant isolation, admin mutation, export creation, billing mutation, data-residency routing, legal-gated adoption/workforce views, and support break-glass access. On error, timeout, ambiguity, or missing input, these deny, with zero data egress and an audit entry.
This split is exhaustive and frozen. There is no feature flag that converts a fail-closed path to fail-open. The decision-time interceptor forwards your traffic when in doubt; the security boundary denies access when in doubt. Both behaviors are tested directly.
Where customer data lives and where it does not¶
| Data | Where it lives | Where it never goes |
|---|---|---|
| Invocation events, attribution graph, materialized index | In the dedicated tenant data plane (your cloud in self-hosted mode or your contracted SaaS lane) | Venturi’s control plane or shared environments |
| Cost / usage / identity signals | Read into your data plane | Written back to your environment (read-only) |
| Prompt and completion content | Nowhere persisted | Where a default cloud read grant reaches content-bearing logs, the collector discards bodies and content-shaped keys in memory; the normalized schema has no content field |
| Provider admin keys | KMS-encrypted in your tenant boundary | Venturi control plane never sees plaintext |
No content capture, by design
The core pipeline never stores prompt or completion text. The canonical
InvocationEvent schema has no content field at all. Attribution is
built entirely from metadata: model, tokens, cost, identity, timing. This
is structural, not configurable: there is no setting that turns content
capture on. The default cloud read grants (CloudWatch Logs on AWS,
roles/ on Google Cloud, Reader and Monitoring Reader on
Azure) can reach content-bearing logs, such as provider content logging you
enable and Vertex AI container logs, which are on by default. The
collector discards content fields in memory before a record is
materialized; see Trust & security.
Data that does live in your plane is retained for 13 months by default (configurable from 30 days to 5 years), encrypted at rest with a customer-managed key (one key per tenant) and in transit with TLS. Per-subject erasure crypto-shreds the subject’s key within 30 days and issues an erasure certificate. See Data privacy & retention for the full data-handling model.
Energy and carbon attribution¶
Because the attribution graph already knows which model served each invocation and how many tokens it consumed, Venturi projects the same graph onto energy and carbon accountability. Each invocation is attributed energy (Wh/kWh) and carbon (gCO2e) from a model-and-region catalog, rolled up the same six layers so a team, service, or budget can see its AI energy and carbon alongside its cost. See Energy and carbon attribution.
Null is not zero
When a model is not in the energy/carbon catalog, Venturi reports the value as null (unknown coverage), never as zero. It will not understate impact by treating missing catalog coverage as no impact, and energy multipliers are never restated as cost figures.
How it fits together¶
- To connect a cloud and start producing attribution, see Quickstart and the onboarding guides.
- To send request-level events for per-call resolution, see Ingestion.
- For the security-reviewer view of read-only enforcement, no-content-capture, and fail-open, see Trust & security.
- For a shorter conceptual overview, see How Venturi works.
The trust & security model in full
Sign in to send feedback. Opens in a new tab.
Copy page details
Docs feedback: System architecture
Page: https://docs.venturi.systems/concepts/system-architecture/