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 failsconformance/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
*Detailsmethod when you needreasonor error fields
fw.isOn. That symbol is not in the SDK.
How it relates
The nine methods
Every SDK exposes the surface under a namespace namedcontrolPoints, 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 yourdefault 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:- key — non-empty, ≤256 characters, no control characters
- default vs type —
getBooleanValuewith a non-boolean default isTypeMismatch - context — depth, key count, value size, reserved keys
- lifecycle — not
NotReady, notAlreadyClosed
The Decision
SPLIT is a Decision reason, not a ramp controller. The SDK does not advance percentages.
What it looks like
- Node
- Web
- Python
- Go
- Java
- Rust
- Swift
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.
