Feature flags

What it does

The packages/flags cartridge38 evaluates typed flags. A flag declares its name, schema25, default, owner, purpose, removal date, and evidence ladder7.ΒΆ

Each rung names its authority and exit measurements. A read scope7 is the partition for a flag value and its evidence. A child schema defines it; the default is global.ΒΆ

Handlers request the Flags service26 from core. The Config adapter27 reads deployment configuration. The memory adapter supplies rules and writable values for tests.ΒΆ

The KV adapter owns its namespace through Alchemy. Under the default policy, missing KV values use Config values or declared defaults. The refuse policy returns a typed failure on a missing or failed replica read.ΒΆ

EVENTS_ENABLED defaults to false and stays deploy-time Config. Live KV writes cannot change this flag.ΒΆ

EVENTS_IDENTITY_MODE defaults to daily. The Worker reads its live value for each captured request. Config keeps the existing environment keys and boolean spellings. An empty KV namespace preserves Config behavior.ΒΆ

Invalid Config stops initialization. A failed KV read follows the catalog’s failurePolicy. The default policy returns the declared default. The refuse policy preserves the typed failure.ΒΆ

Previews use Config and declare no flags namespace. The production Worker and content backend read KV.ΒΆ

Alchemy still selects analytics resources during deployment. See Analytics18 for capture and identity behavior.ΒΆ

The standard

Three operator capabilities replace the raw setter:ΒΆ

Climbs use the capability approval service. Above agent, they also need an approvalRef quote. The roles are agent, arbiter, and owner. Token checks belong in the child’s composition.ΒΆ

off bypasses approval and still records its caller in the attempt ledger.ΒΆ

The CLI accepts --yes or asks for interactive approval on a climb. Its default composition has no live ledger and returns a named error.ΒΆ

The CLI records local-cli as a channel label. Its caller has no authenticated person identity.ΒΆ

The public Worker, RPC readers, and read-only sandbox expose no flag writes. A child mounts its operator surface25 and supplies its approval policy and ledger adapter.ΒΆ

Each available-store attempt records its caller, flag, observed old value, requested value, time, and outcome. The journal stores an immutable Pending key before the approval gate. A separate completion key records success, denial, failure, or interruption. Both keys share an attempt id.ΒΆ

Missing completion means Pending with an unknown result. A failed completion write returns a typed error; the flag may have changed. Audit storage failures block only writes. Config and default journals use composition-local memory.ΒΆ

A projection is a copy derived from a committed value.ΒΆ

The default operator adapter uses one Durable Object per flag and scope. It serializes transitions and commits the value, receipt, and dirty projection marker together. An alarm projects that committed value to KV. Failed projection keeps the marker for redrive14.ΒΆ

Readers use KV and never call the Durable Object.ΒΆ

KV changes may take 60 seconds or more to reach another location. The observed old value in an attempt may be stale. Climb validation uses the DO’s authoritative position. Use deployment settings or a stronger control path for kill switches and safety stops.ΒΆ

The explicit KV ledger fallback keeps immutable attempt and outcome keys. It refuses authoritative flips and evidence writes with FlagAtomicityRequired by default. A composition can opt in with authoritativeWrites: "accept-non-atomic-unserialized".ΒΆ

That option accepts the absence of atomic commit and cross-isolate serialization. Writes to the same KV key can hit its one-write-per-second limit.ΒΆ

The crash-recovery proof uses a persisted service double. Native workerd transaction and alarm behavior still needs provider qualification. The operator ledger is not wired into the deployed Stack.ΒΆ

The lifecycle journal is scoped memory, with no durable state between processes.ΒΆ

How to check

  1. Run pnpm --filter @rat-stack/flags test for rollout properties, generated write histories, audit failures, and lifecycle histories.ΒΆ
  2. Run pnpm --filter @rat-stack/core exec vitest run test/patterns-rule.test.ts for the removal-date fence45.ΒΆ
  3. Run pnpm turbo run check test build --concurrency=1 for the full gate.ΒΆ
  4. Inspect the deployment plan. Readers declare one KV namespace. The operator layer18 adds the ledger DO and its KV write binding23.ΒΆ
  5. Follow Add a feature flag for scoped evidence, authority, and crash-redrive checks.ΒΆ

To remove the cartridge38:ΒΆ

  1. Replace apps/site/src/flags.ts with core imports.ΒΆ
  2. Export flagsLayer = Flags.defaults(eventFlags) and liveFlagsLayer = flagsLayer.ΒΆ
  3. Remove the package dependency and its directory.ΒΆ

Callers keep their typed defaults. The CLI retains its named read-only failure.ΒΆ

Sources

  1. Flags cartridge. rat-stack. Evaluation, adapters, audit journal, lifecycle, and behavior tests. Accessed 2026-10-11.
  2. How KV works. Cloudflare. Eventual consistency, cached missing keys, and no atomic transactions. Accessed 2026-10-11.
  3. Workers KV limits. Cloudflare. One write per second to each key. Accessed 2026-10-11.

Last changed 2026-10-24 in 777b9ba. Source on GitHub. Change log.

Linked from

  1. add-a-feature-flag. Declare a typed feature flag, its scoped evidence ladder, approval roles, removal date, and durable ledger adapter.

    Read Flags climb on evidence and Feature flags first.ΒΆ

  2. Agent guide. An Effect stack so pure (aspirational) Kit Langton will blush.

    Feature flags β€” Typed feature flags with owners, removal dates, and stable subject rollouts.

  3. Change log. What changed in the files served here, newest first.

    Feature flags β€” edited: fix(flags): refuse non-atomic KV authority by default

  4. Durability. Seven durable Effect patterns, each with its seam, its fence, and the incident that taught it.

    Seam: the flags cartridge.

  5. Flags climb on evidence. A flag ladder connects each rollout step to scoped measurements, approval, and a durable receipt.

    A feature flag declares a ladder of values.

  6. Full agent guide. An Effect stack so pure (aspirational) Kit Langton will blush.
  7. Learn the stack | rat-stack. Hands-on guides to Effect actions, XState lifecycles, and the seams between stack pieces.

    add-a-feature-flag β€” Declare a typed feature flag, its scoped evidence ladder, approval roles, removal date, and durable ledger adapter.

  8. Rat Stack systems | rat-stack. The systems rat-stack ships, the standard each keeps, and how to check it.

    Feature flags β€” Typed feature flags with owners, removal dates, and stable subject rollouts.

  9. Source change history (log.md). The generated change log as Markdown.

    Feature flags β€” edited: fix(flags): refuse non-atomic KV authority by default