Connectors

A connector's lifecycle: why every instance starts Draft and Mock

Going live is a separate, deliberate act from creating a connector — every new instance seeds unable to call anything, by construction, until someone says otherwise.

By The Kav team Published 2 min read

A connector instance is addressed by two independent properties — its status and its mode — and the whole design of this screen is that neither one is a convenience toggle. Both are real, auditable decisions.

Creation never reaches a real system

Every new instance you create — through the modal at /connectors, naming a slug, which definition it binds to, a base URL and a vault key — comes into existence Draft and Mock, with no exception. ConnectorInvoker on the backend refuses to call anything through a non-Active instance, so this is safe by construction: a deploy, a bulk import, an accidental double-click on create can never cause a single outbound call to a municipal system.

Status and mode, and what each one actually answers

  • Status — Draft, Active or Suspended. Whether this instance is allowed to be used at all right now.
  • Mode — Live, Mock or Record. Whether calls actually leave the machine, get answered from a fixture, or get recorded for later replay.

They're separable because they fail in different ways. An instance can be Active and still Mock — wired into bindings, reachable in every screen that lists it, and still not touching a real vendor. Going properly live means both Active and a non-Mock mode at once.

The lifecycle form warns you before submission whenever you're about to set Active together with a non-Mock mode — this is the one combination that actually lets a resident's turn reach a real municipal system, and the submit button itself switches to a danger style in that state.

The server pre-flights the one failure that would otherwise be silent

Setting Active with a real (non-Mock) mode is refused outright if the credential vault holds no entry for this instance's vault key — not a warning, a refusal. Without that check, an operator would see a clean success, and the first resident to ask a question through it would get an authentication failure from a log nobody happened to be watching. The lifecycle panel shows you the credential fingerprint the switch actually resolved (or explicitly that none was found) the moment the mutation succeeds, so you know immediately rather than the next time something breaks.

It's an act, not a flag

setConnectorInstanceLifecycle is the only path that can ever move an instance out of Draft+Mock, and every call to it is a mutation with an actor, a timestamp and an audit record behind it — not a boolean flipped somewhere in configuration. That's deliberate: going live is one of the moments this platform's fail-closed discipline is easiest to accidentally weaken, so it's built to require a specific, named, logged decision rather than a side effect of something else.

Base URL and definition-version overrides on the lifecycle form both accept an empty box as "leave it as it is" — submitting an actually-empty string for either is refused rather than silently accepted as a real change.