Skip to main content

Examples

Task-oriented manifest patterns. Each section is a single scenario with the complete TOML answer and links back to the reference pages that explain the underlying primitives.

The patterns are written to lint clean. Use them as starting points for your own files; rename keys, replace segment audiences, adjust ranges.


Ship a boolean kill-switch

Goal. A single boolean flag that defaults to off everywhere, with on for internal employees as a quick safety net.

# flags/feature-x.toml
schema_version = "0.1"

[flag]
type = "boolean"
description = "Enable the new feature-X behavior. Used as a kill-switch."
owner = "feature-team"
lifecycle = "active"
tags = ["feature-x", "kill-switch"]

[flag.variants]
on = true
off = false

[flag.environments._]
variant = "off"

[[flag.environments._.rules]]
description = "Internal employees opt in"
segment = "internal-employees"
variant = "on"
# segments/internal-employees.toml
schema_version = "0.1"

[segment]
description = "Internal employees, identified by email domain."

[segment.predicate]
attribute = "user.email"
op = "ends_with"
value = "@example.com"

To kill the rollout in production, add a self-contained env block:

[flag.environments.production]
variant = "off"

_ is never consulted in production once that block exists.

→ See: flag § Variants, segment § Predicate only, resolution.


Roll out a feature to 10% of users

Goal. Send 10% of users to the new behavior, deterministically by their user.id. The rollout monotonically expands by raising end.

# segments/feature-x-rollout.toml
schema_version = "0.1"

[segment]
description = "First 10% of users for the feature-X rollout."

[segment.bucket]
entity_id_attribute = "user.id"
salt = "feature-x-2026"
start = 0
end = 999
# flags/feature-x.toml
schema_version = "0.1"

[flag]
type = "boolean"

[flag.variants]
on = true
off = false

[flag.environments._]
variant = "off"

[[flag.environments._.rules]]
description = "10% rollout"
segment = "feature-x-rollout"
variant = "on"

To expand to 25%, edit only end:

[segment.bucket]
end = 2499

Because salt is stable and start = 0, every user already in the segment stays in. The rollout is monotonic.

→ See: buckets, buckets § Multi-step rollouts.


Run an A/B/C test (three-way split)

Goal. Split traffic roughly equally across three variants, sharing one salt so the three segments partition the assignment space.

# flags/homepage-banner.toml
schema_version = "0.1"

[flag]
type = "string"
description = "A/B/C test for homepage banner copy."
owner = "growth-team"
lifecycle = "active"
tags = ["experiment", "copy"]

[flag.variants]
control = "Payments made simple."
variant_a = "Send money in seconds."
variant_b = "The fastest way to pay."

[flag.environments._]
variant = "control"

[[flag.environments._.rules]]
description = "First 33% bucket: control"
segment = "banner-bucket-control"
variant = "control"

[[flag.environments._.rules]]
description = "Second 33% bucket: variant A"
segment = "banner-bucket-variant-a"
variant = "variant_a"

[[flag.environments._.rules]]
description = "Final ~34% bucket: variant B"
segment = "banner-bucket-variant-b"
variant = "variant_b"
# segments/banner-bucket-control.toml
schema_version = "0.1"

[segment]
description = "Control bucket (first 33%) for the banner experiment."

[segment.bucket]
entity_id_attribute = "user.id"
salt = "homepage-banner-2026"
start = 0
end = 3299
# segments/banner-bucket-variant-a.toml
schema_version = "0.1"

[segment]
description = "Variant-A bucket (second 33%)."

[segment.bucket]
entity_id_attribute = "user.id"
salt = "homepage-banner-2026" # same salt
start = 3300
end = 6599
# segments/banner-bucket-variant-b.toml
schema_version = "0.1"

[segment]
description = "Variant-B bucket (final ~34%)."

[segment.bucket]
entity_id_attribute = "user.id"
salt = "homepage-banner-2026" # same salt
start = 6600
end = 9999

→ See: buckets § Shared salt — three-way A/B/C split.


Gate behind a paid tier

Goal. Pro and enterprise customers see one set of values; free customers see another.

# segments/pro-or-enterprise.toml
schema_version = "0.1"

[segment]
description = "Customers on the pro or enterprise plan."

[segment.predicate]
attribute = "user.plan"
op = "in"
values = ["pro", "enterprise"]
# flags/max-attachments.toml
schema_version = "0.1"

[flag]
type = "integer"
description = "Maximum attachments per message."
owner = "platform-team"
lifecycle = "active"

[flag.variants]
free = 5
pro = 25

[flag.environments._]
variant = "free"

[[flag.environments._.rules]]
description = "Pro and enterprise customers get the higher limit"
segment = "pro-or-enterprise"
variant = "pro"

→ See: predicates § in / not_in, flag § flag.type = "integer".


Geo-fence to a list of countries

Goal. A feature is only available in the US, Canada, and the UK.

Inline (one-off):

[[flag.environments._.rules]]
description = "Available in US/CA/GB"
variant = "on"
predicate = { attribute = "user.country", op = "in", values = ["US", "CA", "GB"] }

Or as a named segment (reusable across flags):

# segments/launch-countries.toml
schema_version = "0.1"

[segment]
description = "Countries the feature has launched in."

[segment.predicate]
attribute = "user.country"
op = "in"
values = ["US", "CA", "GB"]
[[flag.environments._.rules]]
description = "Available in launch countries"
segment = "launch-countries"
variant = "on"

Prefer the named segment whenever more than one flag uses the same audience.

→ See: flag § Inline predicates, segment § Predicate only.


Stage a rule with the testing gate

Goal. Roll out a rule in production but only to callers that explicitly opt in (e.g., an internal admin tool). Everyone else sees the existing behavior.

# Day 1 — testing in production.
[flag.environments.production]
testing = true
variant = "off"

[[flag.environments.production.rules]]
description = "Admin preview"
segment = "internal-admins"
variant = "on"

The admin tool calls the SDK with include_testing = true; everyone else's calls (without the opt-in) see off.

When ready to expose to all production traffic, just flip the gate off:

# Day 7 — out of testing.
[flag.environments.production]
variant = "off"

[[flag.environments.production.rules]]
description = "Admin preview"
segment = "internal-admins"
variant = "on"

Same rules, same variant, no churn — only the testing field changed.

→ See: resolution § The rollout workflow.


Retire a flag safely

Goal. A flag has fully rolled out, its callers are being deleted, and you want lint to surface anyone who reintroduces work on it.

Step 1 — mark it retired but keep the rules running:

[flag]
type = "boolean"
lifecycle = "retired"

[flag.variants]
on = true
off = false

[flag.environments._]
variant = "on"

[[flag.environments._.rules]]
segment = "internal-employees"
variant = "on"

Lint emits W002 ("retired flag still has rules"). The flag still evaluates normally — retirement is a signal, not a switch.

Step 2 — once code references are gone, delete the file. The next manifest version simply omits it.

→ See: flag § lifecycle semantics, diagnostics § W002.


Suppress an attribute from telemetry

Goal. The SDK passes user.email for predicate matching, but you don't want it appearing in evaluation records.

At the flag-namespace level (applies to every flag):

# namespace.toml
[namespace]
slug = "payments"
private_attributes = ["user.email", "user.phone", "request.ip"]

Or for one flag only:

[flag]
type = "boolean"
private_attributes = ["user.email"]

The effective filter is the union of namespace and per-flag lists. The SDK strips matched names from context_attributes (and secondary_unit_ids keys) before record emission.

→ See: namespace § private_attributes, flag § private_attributes.


Multivariate JSON configuration per tier

Goal. Rate-limit configuration that differs per plan, returned as a JSON object the SDK can deserialize.

# flags/rate-limits.toml
schema_version = "0.1"

[flag]
type = "json"
description = "Per-tier API rate-limit configuration."
owner = "platform-team"
lifecycle = "active"

[flag.variants]
free = { tier = "free", per_minute = 60, per_day = 10000 }
pro = { tier = "pro", per_minute = 600, per_day = 100000 }
enterprise = { tier = "enterprise", per_minute = 6000, per_day = 1000000 }

[flag.environments._]
variant = "free"

[[flag.environments._.rules]]
description = "Pro and enterprise customers get higher rate limits"
segment = "pro-or-enterprise"
variant = "pro"

# Pre-prod: pin to the highest tier so QA can hit limits deterministically.
[flag.environments.development]
variant = "enterprise"

[flag.environments.staging]
variant = "enterprise"

→ See: flag § flag.type = "json".


Bucket inside a stable audience

Goal. Roll out variant A to the first 10% of beta users — not the first 10% of all users.

# segments/beta-users-variant-a.toml
schema_version = "0.1"

[segment]
description = "First 10% bucket within the beta cohort."

[segment.predicate]
segment = "beta-users"

[segment.bucket]
entity_id_attribute = "user.id"
salt = "feature-x-beta-2026"
start = 0
end = 999
# flags/feature-x.toml
[[flag.environments.production.rules]]
description = "Variant A for the first 10% of beta users"
segment = "beta-users-variant-a"
variant = "variant_a"

The predicate is checked first; if beta-users doesn't match, the bucket hash is not computed.

→ See: segment § Both (predicate + bucket hybrid), buckets § Bucket constrained by predicate.


A complete reference manifest

A self-consistent example exercising the full feature surface — boolean kill-switch, multivariate string flag, integer config, JSON config, predicate segments, bucket segments, hybrid segments, segment composition, per-environment overrides. Every file lints clean (zero errors, zero warnings, zero infos). The flag namespace is for a fictional payments team; the slug is payments.

Directory tree

payments/
namespace.toml
flags/
checkout-redesign.toml
homepage-banner-copy.toml
max-attachments-per-message.toml
rate-limits.toml
segments/
beta-users.toml
checkout-redesign-rollout-10.toml
homepage-banner-bucket-control.toml
homepage-banner-bucket-variant-a.toml
homepage-banner-bucket-variant-b.toml
internal-employees.toml
internal-or-beta-users.toml
pro-or-enterprise-customers.toml

namespace.toml

schema_version = "0.1"

[namespace]
slug = "payments"
display_name = "Payments Team"
description = "Feature flags for the payments service and checkout domain. Contact #payments-platform on Slack."
telemetry_enabled = true

[namespace.environments]
development = { display_name = "Development" }
staging = { display_name = "Staging" }
production = { display_name = "Production" }

flags/checkout-redesign.toml

A boolean kill switch with a phased rollout in production.

schema_version = "0.1"

[flag]
type = "boolean"
description = "Routes /checkout to the redesigned flow introduced in Q2 2026."
owner = "payments-team"
lifecycle = "active"
tags = ["checkout", "rollout", "q2-2026"]

[flag.variants]
on = true
off = false

# Catch-all: production-shaped behavior — off, with a phased rollout.
[flag.environments._]
variant = "off"

[[flag.environments._.rules]]
description = "Internal employees and beta program users get the new flow first"
segment = "internal-or-beta-users"
variant = "on"

[[flag.environments._.rules]]
description = "10% rollout to general population"
segment = "checkout-redesign-rollout-10"
variant = "on"

# Pre-prod: always on, no rules.
[flag.environments.development]
variant = "on"

[flag.environments.staging]
variant = "on"

flags/homepage-banner-copy.toml

A multivariate string flag for an A/B/C copy test. All three variants receive approximately equal traffic via three percentage-bucket segments sharing one salt.

schema_version = "0.1"

[flag]
type = "string"
description = "A/B/C test for homepage banner headline copy."
owner = "growth-team"
lifecycle = "active"
tags = ["experiment", "copy", "homepage"]

[flag.variants]
control = "Payments made simple."
variant_a = "Send money in seconds."
variant_b = "The fastest way to pay."

# Catch-all carries the production-shaped behavior.
[flag.environments._]
variant = "control"

[[flag.environments._.rules]]
description = "First 33% bucket: control"
segment = "homepage-banner-bucket-control"
variant = "control"

[[flag.environments._.rules]]
description = "Second 33% bucket: variant A"
segment = "homepage-banner-bucket-variant-a"
variant = "variant_a"

[[flag.environments._.rules]]
description = "Final ~34% bucket: variant B"
segment = "homepage-banner-bucket-variant-b"
variant = "variant_b"

# Pre-prod: pin to control so screenshots are deterministic.
[flag.environments.development]
variant = "control"

[flag.environments.staging]
variant = "control"

flags/max-attachments-per-message.toml

An integer-config flag with a different value per customer tier.

schema_version = "0.1"

[flag]
type = "integer"
description = "Maximum number of attachments allowed on a single message."
owner = "platform-team"
lifecycle = "active"
tags = ["limits"]

[flag.variants]
free = 5
pro = 25
enterprise = 100

[flag.environments._]
variant = "free"

[[flag.environments._.rules]]
description = "Pro and enterprise customers get higher limits"
segment = "pro-or-enterprise-customers"
variant = "pro"

[flag.environments.development]
variant = "enterprise"

[flag.environments.staging]
variant = "enterprise"

flags/rate-limits.toml

A JSON-typed flag holding a structured rate-limit configuration.

schema_version = "0.1"

[flag]
type = "json"
description = "Per-tier API rate-limit configuration."
owner = "platform-team"
lifecycle = "active"
tags = ["limits", "config"]

[flag.variants]
free = { tier = "free", per_minute = 60, per_day = 10000 }
pro = { tier = "pro", per_minute = 600, per_day = 100000 }
enterprise = { tier = "enterprise", per_minute = 6000, per_day = 1000000 }

[flag.environments._]
variant = "free"

[[flag.environments._.rules]]
description = "Pro and enterprise customers get higher rate limits"
segment = "pro-or-enterprise-customers"
variant = "pro"

[flag.environments.development]
variant = "enterprise"

[flag.environments.staging]
variant = "enterprise"

segments/beta-users.toml

A predicate segment for users who opted into the beta program.

schema_version = "0.1"

[segment]
description = "Users who have explicitly opted into the beta program."

[segment.predicate]
attribute = "user.beta_opt_in"
op = "eq"
value = true

segments/internal-employees.toml

A predicate segment for internal team members, identified by email domain.

schema_version = "0.1"

[segment]
description = "Internal employees, identified by email domain."

[segment.predicate]
attribute = "user.email"
op = "ends_with"
value = "@example.com"

segments/internal-or-beta-users.toml

A composed segment that references two other segments.

schema_version = "0.1"

[segment]
description = "Internal employees or users enrolled in the beta program."

[segment.predicate]
or = [
{ segment = "internal-employees" },
{ segment = "beta-users" },
]

segments/pro-or-enterprise-customers.toml

A predicate segment using in to match a list of plans.

schema_version = "0.1"

[segment]
description = "Customers on the pro or enterprise plan."

[segment.predicate]
attribute = "user.plan"
op = "in"
values = ["pro", "enterprise"]

segments/checkout-redesign-rollout-10.toml

A percentage-bucket segment for a 10% rollout, with an explicit salt.

schema_version = "0.1"

[segment]
description = "First 10% of users for the checkout redesign rollout."

[segment.bucket]
entity_id_attribute = "user.id"
salt = "checkout-redesign-2026"
start = 0
end = 999

segments/homepage-banner-bucket-control.toml

The control bucket for the homepage banner A/B/C test. The three banner segments share a salt to partition one assignment space.

schema_version = "0.1"

[segment]
description = "Control bucket (first 33%) for the homepage banner A/B/C test."

[segment.bucket]
entity_id_attribute = "user.id"
salt = "homepage-banner-copy-2026"
start = 0
end = 3299

segments/homepage-banner-bucket-variant-a.toml

schema_version = "0.1"

[segment]
description = "Variant-A bucket (second 33%) for the homepage banner A/B/C test."

[segment.bucket]
entity_id_attribute = "user.id"
salt = "homepage-banner-copy-2026"
start = 3300
end = 6599

segments/homepage-banner-bucket-variant-b.toml

schema_version = "0.1"

[segment]
description = "Variant-B bucket (final ~34%) for the homepage banner A/B/C test."

[segment.bucket]
entity_id_attribute = "user.id"
salt = "homepage-banner-copy-2026"
start = 6600
end = 9999

Walking through an evaluation

Given the manifest above, suppose the SDK calls:

client.bool_flag("checkout-redesign", &ctx, false /* default */)

with this evaluation context:

{
"user.id": "u_abc123",
"user.email": "alice@example.com",
"user.plan": "pro",
"user.country": "US"
}

In the production environment:

  1. Look up flag checkout-redesign. Found.
  2. Look up [flag.environments.production]. Not declared in this manifest — production falls through to _.
  3. Walk [flag.environments._].rules:
    • Rule 0: segment internal-or-beta-users.
      • internal-employees predicate: user.email ends_with "@example.com"alice@example.com matches → true.
      • The or short-circuits at true; internal-or-beta-users matches.
      • Return: variant = "on", value = true, rule_matched = "rule:0".

If the user's email had not been internal, evaluation would have continued to Rule 1 (checkout-redesign-rollout-10), computed the bucket from user.id, and returned on if the bucket was in [0, 999] or fallen through to _'s variant = "off" otherwise.

In the development environment, [flag.environments.development] is declared with variant = "on" and no rules. Step 2 returns "on" immediately; _ is never consulted in development.

Lint result

$ exd lint ./payments

0 errors, 0 warnings, 0 infos
passed: true

Or as JSON:

{
"namespace": "payments",
"manifest_version": null,
"errors": [],
"warnings": [],
"infos": [],
"passed": true
}

Every flag has an owner and description (no I001 / I002). Every segment has a description (no I003). Every bucket segment has an explicit salt (no W004). Every flag declares [flag.environments._] with a variant (no E037 / E038). Every flag has rules in at least one env block (no W003). No predicate is empty (no W007). No flag is retired-with-rules (no W002). Every file declares the same schema_version = "0.1" (no W008). This is the gold-standard shape — production manifests should aim for the same zero-diagnostic state.


See also