Skip to content

Static and dynamic

A feature is two different things depending on who asks.

Static is the question a tool asks of itself while it builds: which commands exist, what a help screen lists, what completion offers, what a diagnostic inventories, what a code generator scaffolds. Those answers must be fixed at construction, from the binary's imports and the tool's own choices, so that --help is the same offline as online and a CI run sees the same CLI as a laptop. Set.Enabled answers them.

Dynamic is the question a service asks per request: is this experiment on for this user, has this kill switch been thrown. Those answers may come from a backend, may be targeted at a subject, may fail, and need a fallback. Evaluator.Evaluate answers them.

The line is enforced by the descriptor, not by convention. A descriptor that does not report IsDynamic is static-only, and no evaluator will return anything but its Set state for it, whatever a backend says. A tool declares a dynamic feature the same way it declares any other, so the same inventories know it exists, and its static state is its fallback: the tool's own decision, made once, in the one place an offline default can honestly live.

Set implements Evaluator with the static answer, so a service can be wired with a Set today and take a Dynamic tomorrow without a call-site change. No vendor SDK enters this module; each backend is an adapter module, so a tool links only what it uses.