Skip to main content
A stage is a unit of behavior attached to a VPoint. The user-facing kind is a CEL stage: a small expression, pushed from a test, that controls what the VPoint does for calls in your session.

The pipeline

Every VPoint call runs through a fixed sequence of anchors — slots where stages can attach:
A stage that produces a value short-circuits the rest of the pipeline; a stage that passes through lets execution continue. With no stages attached, the call takes a fast path straight to the default plan — the original function, exactly as written.

The three stage patterns

Almost every test uses one of three shapes. Inside a CEL expression, args.<param> reads the call’s inputs and invoke() executes the next stage or the real function. Override — replace the result entirely. The real function never runs:
Conditional override — intercept some calls, pass the rest through:
Probe — observe without changing behavior. sample() captures a value for the test to assert on and returns it unchanged:
The captured sample streams back to your test session, where you assert on it:

Validated against the schema

CEL stages compile against the VPoint’s schema when inserted. Type names, field names, and required fields are all checked — ChargeResult { txn: ... } fails at insert time if the field is txnId. This is why inspecting the schema first (via the MCP tools or your SDK’s build-time output) beats guessing. Key rules:
  • Inputs are read only through args.<param> — a bare parameter name is rejected at parse time.
  • Type names match the schema exactly and are case-sensitive; use the simple name (ChargeResult, not pb.ChargeResult).
  • Without invoke(), the expression fully replaces the function’s result.
  • ctx.<fn>(...) calls context functions your service registered.
The full expression language — operators, optionals, list predicates, let bindings, and current limitations — is in the CEL reference.

Beyond CEL

The TypeScript SDK can also attach local JS function stages and debug/logging stages directly in-process, without the registry — useful for local development and framework integration. See TypeScript SDK → Stages. CEL stages are the portable, registry-delivered kind that tests use across all languages.