Skip to main content
A VPoint (variation point) is a named seam around a function or method. You register it once at startup; every call then routes through the Varianz pipeline, where session-scoped stages can sample inputs and outputs or override the result. The model is the same in every language: register once, call many. Get a runtime handle, register your VPoints against it, then call the returned or instrumented function per request.
Three properties make VPoints safe to adopt incrementally:
  • Pass-through by default. With no stages attached (or with the SDK disabled), a VPoint runs the original function directly on a fast path. You can merge instrumentation before any coordinator exists.
  • You choose what to instrument. Varianz doesn’t require instrumenting all your code — annotate the functions that matter: payment charges, external calls, decision points you want to test around.
  • Session-scoped control. CEL stages attach per test session; traffic without a session ID never sees them. (In-process local stages are the deliberate exception — they belong in test processes only.)

Names

Every VPoint has a name. Give it explicitly, in scope/entity form:
Names are kebab-case segments separated by /. The first segment is a logical grouping (often the owning domain or service area); the last is the operation. Under the hood, names canonicalize to a four-part form (org/pkg/scope/entity) with the missing parts derived from your code’s package structure — tests can target a VPoint by any unambiguous suffix on / boundaries. See Naming and routing for the full rules.
Always name VPoints explicitly. Auto-derived names come from package and class names, which makes them fragile under refactoring.

Schemas

When a VPoint registers, the SDK derives a schema from the function’s parameter and return types — field names, types, and nested structures. The schema is what CEL expressions are validated against, so a typo’d field name or a wrong type is reported as a validation issue rather than misbehaving at runtime. That validation is advisory — it does not block the insert or fail the sync barrier — so check the issues it reports. Where the schema comes from differs by language: Prefer the static path (annotations, scanner, codegen) — a lazily-resolved VPoint still takes its stages, but its expressions are not validated until the schema resolves, so mistakes surface at call time instead of at insert time. See Build integration.

VPoints in each language

The registration idiom follows each language’s conventions — decorators in Python and TypeScript, a higher-order wrapper in Go, annotations in Java and Kotlin: For the step-by-step walkthrough, see Instrument a service.