> ## Documentation Index
> Fetch the complete documentation index at: https://docs.artbucket.io/llms.txt
> Use this file to discover all available pages before exploring further.

# 0018: Features are switched on and off, by the organization or each project

> Accepted. The core's own features and the server's, in one list an admin governs.

## 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_off` and 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's `gates`).
* 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.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.