Service virtualization

A gateway calls something outside your application. Service virtualization generates a stand-in for it, so the whole flow runs with nothing installed and no credentials.

sub-domains/notifications/gateways/mailer.vishwakarma
gateway MailerGateway {
  http {
    base_url_env "MAILER_URL"
    auth bearer_token: "MAILER_API_TOKEN"
  }

  virtual {
    mode mock
    key  "mailer"
    environments { local proxy }
  }

  // … operations …
}

mode mock makes the framework generate a stand-in answering from the declared response shapes. A developer runs the entire booking flow — including the confirmation email — with no account, no key and no mail server. Point MAILER_URL and the token at a real provider and nothing in the model changes: going from a real supplier to a virtual one is a binding change, not a code change.

📋 Availability. Declaring virtual { … } is fully supported: it type-checks, it generates, and the toolchain below works. Turning a stand-in on for a deployed application is currently an operator-level setting on the hosting environment, and is not yet self-serve for a hosted app. Locally and in your own environments it works as described.

The four modes

ModeBehaviour
mockanswer from the declared response shapes. No supplier, no capture.
proxyforward to the real supplier and record the exchange on the way through.
replayserve previously recorded exchanges. Offline, deterministic, real bytes.
passthroughforward bytes unmodified, decoding nothing.

mode is the base — what an unnamed environment gets, and what a laptop with nothing reachable gets. environments { <name> <mode> } overrides it for one named deployment. Anything not named falls through to the base.

Why mock alone is not enough

A mock answers from your declaration. That makes it useful for running the app and useless for finding out whether your declaration is right.

proxy is what closes that loop. Forward to the real supplier once, record what it actually said, and the rest of the tooling becomes reachable:

vishwakarma naarad services              # what the estate stands in for
vishwakarma naarad recordings list       # the exchanges captured
vishwakarma naarad recordings show <id>  # both halves, as they crossed the wire
vishwakarma naarad recordings findings   # where your declared shape and the real bytes disagree
vishwakarma naarad promote               # turn recorded exchanges into authored stubs

findings is the payoff. It reports where your declared response shape and the supplier's real bytes disagree — the class of bug a mock can never surface, because a mock answers from the declaration that is wrong.

promote is the point of the loop. A deterministic offline stand-in gets built from what a real provider actually said, rather than written by hand from what somebody assumed it says.

Two consequences worth knowing before enabling a forwarding mode

A forwarding mode records the request body. For an email gateway that body is a rendered message: a recipient address and its contents, written to a durable store. That is fine on a developer's machine and it is not fine on a production authentication path.

A forwarding mode needs an admin credential. The stand-in exposes a runtime stub-registration endpoint. In front of stubs that is a test affordance; in front of a real supplier it is a response-injection primitive, so the credential is mandatory wherever a gateway forwards.

Both are why a forwarding mode belongs on a named environment rather than as the base. The base reaches every deployment, and a mode that forwards live traffic should be opted into somewhere a reviewer can see it:

virtual {
  mode mock                      // everywhere, including production
  environments { local proxy }    // and forwarding only here
}

Choosing what to stand in for

Not everything should be virtualized, and the reasoning is not about convenience.

Standing in for an email provider means a developer needs no account. Standing in for the system that deploys your application would leave it unable to deploy anything, including itself — and it would look healthy while doing it. The failure mode of a wrongly virtualized service is not an error; it is an application that runs, answers successfully, and returns fiction.

So the opt-in is per service and per environment, it defaults to off, and the safe direction is deliberate: an unconfigured environment talks to the real thing.

What it does for assurance

A virtualized operation is still exercised. The assurance report counts obligations that ran against a stand-in rather than treating them as a hole — while recording the substrate, so an obligation needing a real counterparty is not silently marked as proven by a mock.