Context
What an organization could use was the plan’s to say (limits.features), and
nothing let an admin say what it does use: no way to keep AI agents out of
the brand’s files, or to stop share links leaving a regulated team, short of
asking whoever runs the server. A feature the server adds (Intelligence, on
Artbucket Cloud) was turned on at a page of its own, which made the key it
needed itself, so the core didn’t know it was on.
Decision
-
One list of features, in Settings, Features. The core’s own (agents and
API keys, share and upload links, portals and sites, BrandHub, usage
insights) and the server’s, read from
FEATURES_FILE(JSON or YAML), shown alike. Adding one to a server is an entry in that file, never a change to the core. - Switched where it says. Each feature is switched for the organization, each project, or both. On both, the organization turns it on or off in every project, or lets each project decide; the projects’ own choices are kept while it overrides them.
- The plan says what may be used; a switch, what is. A feature its plan doesn’t have shows the way to one that does.
-
Off means off everywhere at once, in the app, the API, MCP and the CLI,
refused with
feature_offand who turned it off. Nothing is deleted. - A server’s feature is told, and may say no. Its hook is called, signed, when it is turned on or off in a project. A refusal (no plan for it) leaves it off, with the reason the admin reads. The core makes the key and the fields the file asks for, hands the key over in that call, and revokes it when the feature is turned off.
-
What a feature reads is held to where it is on. A call made for a
feature says so (
Artbucket-Feature: intelligence), and reaches the projects where that feature is on, of those its caller may open: the catalog, files, and the project a call is in. The header only ever narrows, so no one gains by sending it; one naming a feature the server doesn’t list is ignored.
Consequences
- Off reads as it does for the public: a portal is closed, a brand leaves BrandHub as if private, a link is as if revoked. Usage insights off stops counting; what was counted stays, and Activity (the history of changes) goes on.
- A feature’s key belongs to its switch: Connections leaves it out, and turning agents and keys off leaves it working.
- The server’s pages a feature brings (
ASSISTANT_URL,BRAND_IMPORT_URL) are left out of the app where it is off (the file’sgates). - Turning a feature on in every project calls its hook once per project; one refusal turns none of them on.
- Intelligence’s assistant, in a project where it is on, searches every project of the organization where it is on, and nothing of one where it is off: that content never reaches a model provider.
- A server’s feature may take a plan (
paid): an organization without one reads it as off everywhere, and Settings shows the way to a plan. Its switches are kept, so it comes back as it was. - What a portal or a share link hands out names it in the signature, so its files stop the moment it closes, is revoked or turned off, rather than when the signature runs out a day later.
- Switching asks first when it reaches outside the admin’s view: keys in use,
links, open portals, public listings, counting that can’t be made up, a
server’s own warning (
confirm), or the organization overriding its projects. A dry run (GET /api/v1/features/{id}/impact) counts what would happen; nothing is asked when nothing would.