Add a new feature, put work behind a feature flag, roll something out (per organization, for everyone, cloud or self-hosted), revert or kill a feature, or make a big change to existing behavior such as a new engine. Use BEFORE writing the feature code, and when finishing or removing a rollout.
77
97%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Passed
No findings from the security scan
Every new user-visible feature, and every change existing users would notice, is a feature in the registry, declared before any feature code, off. Nothing big ships ungated.
Registry: packages/features/src/registry.ts (package @openwork/features).
That file is the only one you edit to declare a feature. The rules live in
resolve.ts and are tested in resolve.test.ts
(pnpm --filter @openwork/features test).
A feature is rolled out, and reverted, along these dimensions, resolved in
this order by one function (resolveFeature) everywhere it is checked:
cloud, self_hosted). Fixed in code.config.features.<key>)./admin./admin without a deploy.Steps 2, 4 and 5 are set per deployment in /admin (Features page and each
organization's row) or with the admin MCP tools den_list_features,
den_set_feature_rollout and den_set_org_capability.
Yes, if any of these is true:
No for bug fixes, copy changes, refactors and internal tooling.
Not a feature either: something that only keeps older clients working
(compat shim with a removal condition), something worked out from what is
configured (derive it in code), or a setting that changes how something
works rather than whether people get it (put it in env.ts / Helm config.<area>).
newThing: {
label: "New thing",
description: "What a person gets, in words they see in the product.",
since: "2026-10",
deployments: ["cloud", "self_hosted"],
default: false,
},DEN_FEATURE_NEW_THING, the API field and stored rows.["cloud"] for a cloud-only feature).true.Then run pnpm features:sync. It regenerates the Helm files and the Den API
contract/SDK (feature keys are part of API schemas). It prepares a disposable
local database and removes it afterwards; MySQL must be running
(pnpm dev:den:mysql). Commit the Helm files, packages/docs/openapi.json, and
packages/sdk/src/gen/** together. Do not stop after Helm generation if the
contract step fails.
Before shipping, answer: what happens when the kill switch is used? In-flight work, stored data, and what the person sees must survive a revert. For example, a new engine switches only when nothing is running, falls back on failure, and keeps history readable after a revert.
Only through the registry. Never read organization metadata or an environment variable to decide whether a feature is on.
await organizationFeatureEnabled(orgId, "newThing", { userId })const features = await getOrganizationFeatures(orgId, { userId })requireFeature("newThing") after orgMemberRoute(); answers 404 feature_disabled{ database: tx, lock: "share" }orgFeatureEnabled(orgContext, "newThing") (from app/(den)/_lib/den-org.ts), backed by GET /v1/org featuresGET /v1/features; a missing key means offGated UI follows DESIGN.md P4: show a locked entry point with a plain reason rather than silently removing it, when the person could act on it.
/admin)./admin › Features. Organizations can still be turned off one by one.default: true, then delete the entry and every check. pnpm features:check asks for a decision six months after since unless the entry is permanent.Evals turn features on per organization through the admin API:
enableOrganizationCapabilities(seed, admin, { newThing: true }) in
evals/worlds/dashboards.ts.
DEN_*_ENABLED env var for a product surface (CI rejects new ones).organization.metadata.capabilities (CI rejects it)./admin control, a /v1/org field, or a Helm line for a feature.deployments on purpose.Name the feature and its deployments under "How is this implemented?", e.g.
"Behind newThing (cloud and self-hosted, off), safe to kill: falls back to
the old flow." Run pnpm features:check before
pushing.
different-ai/openwork
acacc7b
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.