Skip to main content
A control point is a named decision the product can change without a deploy. Your application asks Fireweave for a typed value — boolean, string, number, or object — and uses that value to choose a path. The wire, Decision envelopes, conformance fixtures, and capabilities.features.flags still say flagKey. The product name is control point. Do not invent controlPointKey.

Why it exists

Operators reason about a release decision, not “a boolean in a flag console.” Evaluation is still a typed getter so call sites stay small. The nine methods are identical across all seven languages. A language missing any of them fails conformance/surface/.

When to use it

Use a control point whenever your process must choose a value that Fireweave (or a test fixture) owns:
  • Gate a new code path (getBooleanValue)
  • Pick a string variant, numeric threshold, or JSON payload
  • Inspect a full Decision with a *Details method when you need reason or error fields
Do not use an in-app helper named fw.isOn. That symbol is not in the SDK.

How it relates

The nine methods

Every SDK exposes the surface under a namespace named controlPoints, cased for the language: controlPoints (Node, Web, Java, Swift), control_points (Python, Rust), ControlPoints (Go). flags / Flags() is a deprecated alias pointing at the same object. Do not use it in new examples. It is silent at runtime except in Python (one DeprecationWarning per process). *Value returns Decision.value. *Details returns the whole Decision. Both take the same arguments, so you upgrade from one to the other without restructuring the call. Naming follows each language’s idiom (get_boolean_value, GetBooleanValue) but the method set and its semantics do not vary. Python still accepts get_integer_value as a deprecated alias of get_number_value. It logs one DeprecationWarning per process the first time you call it.

Sync vs async

Web and Swift prefetch during initFireweave / identify. A hung prefetch does not block boot. The runtime enters STALE and serves your default with reason STALE. See Lifecycle.

Return discipline

A control-point read never throws. Every failure resolves to your default with a Decision naming the reason. STALE is a reason, not an error. The runtime is serving a usable-but-not-fresh cache. Init is the exception: bad configuration fails loudly at boot. See Configuration. A v1 read is side-effect free. No read emits telemetry as a consequence of being called.

Validation, before any I/O

Implementations validate in this order and stop at the first failure:
  1. key — non-empty, ≤256 characters, no control characters
  2. default vs type — getBooleanValue with a non-boolean default is TypeMismatch
  3. context — depth, key count, value size, reserved keys
  4. lifecycle — not NotReady, not AlreadyClosed

The Decision

SPLIT is a Decision reason, not a ramp controller. The SDK does not advance percentages.

What it looks like

Call-site defaults stay false (or the safe production fallback). Do not write getBooleanValue(key, true) to dogfood locally — that same true is the production fallback when a control point is absent.
Last modified on September 11, 2026