Feature flags
What it does
The packages/flags cartridge36 evaluates typed flags.
A flag declares its name, schema17, default, owner, and removal date.ΒΆ
Handlers request the Flags service16 from core.
The Config adapter19 reads deployment configuration.
The memory adapter supplies rules and writable values for tests.ΒΆ
The KV adapter owns its namespace through Alchemy. Missing KV values use Config values or declared defaults.ΒΆ
listFlagslists names, owners, and removal dates.ΒΆgetFlagevaluates one flag for an optional subject.ΒΆ- Allow-lists select a value for named subjects.ΒΆ
- Percentage rules use a stable hash of the flag name and subject.ΒΆ
- The first matching rule wins. Missing subjects use the default.ΒΆ
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 returns a typed error with its configured fallback recorded.ΒΆ
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
- Flag values pass their declared schemas.ΒΆ
- Every declaration names an owner and a
removeBydate.ΒΆ - Lint rejects declarations without a literal removal date.ΒΆ
- The flags build rejects expired registered events flags with a typed repair message.ΒΆ
- Each subject keeps its rollout bucket when the rollout percentage changes.ΒΆ
- The lifecycle permits
declaredβrollingOutβonβremoved.ΒΆ - Declared Effect17 actors record lifecycle transitions. Removed flags stay removed.ΒΆ
- Each capability21 shares its contract21 across surfaces. JSON encoding is required for
getFlag.ΒΆ
setFlag is an approval-gated capability on the CLI.
The CLI accepts --yes or asks for interactive approval.
Its default composition has no live writer 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 live operator write surface23 and listFlagChanges remain future work.ΒΆ
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.ΒΆ
KV changes may take 60 seconds or more to reach another location. The observed old value may be stale. KV cannot commit a flag value and its audit outcome in one transaction. Unique journal keys avoid its one-write-per-second limit on each key.ΒΆ
Writes to the same flag can still hit that limit and return a typed error.ΒΆ
The lifecycle journal is scoped memory, with no durable state between processes.ΒΆ
How to check
- Run
pnpm --filter @rat-stack/flags testfor rollout properties, generated write histories, audit failures, and lifecycle histories.ΒΆ - Run
pnpm --filter @rat-stack/core exec vitest run test/patterns-rule.test.tsfor the removal-date fence39.ΒΆ - Run
pnpm turbo run check test build --concurrency=1for the full gate.ΒΆ - Inspect the deployment plan. Adding live flags declares one KV namespace and updates its Worker bindings23.ΒΆ
- Replace
apps/site/src/flags.tswith core imports.ΒΆ - Export
flagsLayer = Flags.defaults(eventFlags)andliveFlagsLayer = flagsLayer.ΒΆ - Remove the package dependency and its directory.ΒΆ
Callers keep their typed defaults. The CLI retains its named read-only failure.ΒΆ
Sources
- Flags cartridge. rat-stack. Evaluation, adapters, audit journal, lifecycle, and behavior tests. Accessed 2026-10-11.
- How KV works. Cloudflare. Eventual consistency, cached missing keys, and no atomic transactions. Accessed 2026-10-11.
- Workers KV limits. Cloudflare. One write per second to each key. Accessed 2026-10-11.
Last changed 2026-10-11 in 11edf67. Source on GitHub. Change log.
Linked from
- 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.
- Change log. What changed in the files served here, newest first.
Feature flags β edited: feat(flags): add KV reads and approval-gated audited writes
- Full agent guide. An Effect stack so pure (aspirational) Kit Langton will blush.
- 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.
- Source change history (log.md). The generated change log as Markdown.
Feature flags β edited: feat(flags): add KV reads and approval-gated audited writes