---
id: settings
class: b2
sourced: 2026-07-12
source: "b2b-ux-patterns ch.16"
license: open
---
# Pass: settings

**Inputs:** per settings surface — `isSettingsPage`, `scope` (personal | workspace | org), `settingKind` (leaf-preference | config-object), `riskClass` (preference | behavior-config | structural-destructive), `subject`, `multiScopeSetting`, `nodeCount` (under-30 | over-30), `governedSurfaceLink`, `buildTimeGeneration`, `productSurfaceInTree`.
**Owns:** `archetypes`, `requiredStates`, `requiredMechanics`, `clarifications`.
**Output artifact:** the settings area treated as a **shadow meta-product** — the scope/subject/risk taxonomy, config-objects-not-forms, the interaction tier per risk class, the inheritance cascade, findability, and the AI governance subjects — reusing the whole playbook recursively rather than being hand-designed as a tree of forms.

## The rule

**Settings is not a page tree — it is the product's shadow meta-product**, used by a different persona (admins/builders), at a different frequency (rare), in a different mode (Configuration: deliberate, consequential, preview-hungry). Most of it should reuse the playbook, not be designed as forms.

**Config is objects, not forms.** A large share of "settings" are **config objects with full lifecycles** — webhooks/API keys (an index + detail with delivery logs), roles & permission sets (entity details with related-user lists and an impact surface), pipelines/stages/custom fields (a schema builder — the object model exposed as product), automations (canvas-builder with draft-vs-publish), templates/snippets/brand kits (standing-context assets), notification/SLA policies (config objects with versions and audit). Each has an index, a detail, a create flow, a state machine (draft / enabled / disabled), versioning, and Logged history. **Only leaf preferences — true toggles — are forms.** Designing settings as "a tree of forms" is the root mistake.

**Three orthogonal axes, and the navigation rule.** *Scope* — who it affects: personal / workspace / organization. *Subject* — what it configures: identity & access, data model, automation, notifications, integrations, branding, billing & plan, compliance & audit, and AI & agent policy. *Risk class* — how it takes effect: instant toggle, draft-publish config object, or structural migration. **Navigate by scope first, then subject** — scope maps directly to permissions and to the user's mental question, "am I changing this for me, or for everyone?" **Blast radius is declared, not inferred**: every settings page carries a blast-radius declaration in its header ("Affects only you" / "Affects everyone in Acme Corp") — a required element, the settings-land equivalent of the environment banner — paired with distinct per-scope chrome. Configuration belongs on a full surface, never a context-losing modal.

**Risk class dictates the interaction tier.** *Preferences* (personal, reversible, instant): autosave silently, no confirm — friction here is pure tax. *Behavior config* (affects others, reversible): explicit save plus a changelog entry, and the setting's own Logged history answers "who changed this and when." *Structural & destructive* (schema changes, role edits, SSO, retention, deletion): the full ceremony — **draft → impact preview → publish**, where the impact preview is the load-bearing step ("this role change affects 34 users"; "changing this field type will truncate 1,204 values"); add maker-checker where policy demands, isolate the irreversible in a type-to-confirm **danger zone**, and log everything to the org audit trail. Tier-3 changes deserve the test-before-live discipline of the AI layer's agent CI (simulate the rule against yesterday's traffic before publishing).

**The inheritance cascade — the most underserved settings pattern.** Any setting existing at more than one scope forms a cascade (org default → team override → user override), and the UI must solve the resolved-value problem: show the **effective value** the viewer gets, show **where it came from** ("inherited from Organization" vs "overridden here"), and offer **reset to inherit** as a first-class action distinct from "set to the same value." Once a cascade exists, impersonation/view-as is the only honest debugger. **Findability**: settings search is mandatory past ~30 nodes (admins remember words, not the tree), every setting has a stable deep link, and the in-context gear links bidirectionally between a governed surface and the setting that governs it. **The AI subjects (2026)**: build-time generation compiles NL to an inspectable artifact editable before commit — never a black box; the agent governance console (identities, model-routing, data masking, permission scoping, the AI-action audit view) is a new org-scope subject. Anti-patterns forbidden: the junk drawer, features hiding in settings (saved views, dashboards, templates are product surfaces, not settings), modal settings, and the invisible cascade. A settings page whose scope is undeclared cannot be placed or permissioned: clarify.

```json decision-table
{"pass": "settings", "rows": [
  {"when": {"isSettingsPage": true}, "then": {"archetypes": {"mustInclude": ["settings"]}, "requiredMechanics": {"mustInclude": ["blast-radius-declaration-header", "navigate-scope-first-then-subject", "per-scope-chrome"], "mustNotInclude": ["modal-settings", "settings-as-tree-of-forms"]}}, "reason": "blast-radius-declared-not-inferred"},
  {"when": {"settingKind": "config-object"}, "then": {"requiredMechanics": {"mustInclude": ["config-object-full-surface-set", "config-state-machine", "config-versioning", "config-logged-history"], "mustNotInclude": ["config-as-leaf-form"]}}, "reason": "config-is-objects-not-forms"},
  {"when": {"settingKind": "leaf-preference"}, "then": {"requiredMechanics": {"mustInclude": ["leaf-toggle-form"]}}, "reason": "only-true-toggles-are-forms"},
  {"when": {"riskClass": "preference"}, "then": {"requiredMechanics": {"mustInclude": ["autosave-silent-no-confirm"], "mustNotInclude": ["confirm-on-preference"]}}, "reason": "preference-autosaves-friction-is-tax"},
  {"when": {"riskClass": "behavior-config"}, "then": {"requiredMechanics": {"mustInclude": ["explicit-save", "changelog-entry", "logged-history"]}}, "reason": "behavior-config-logs-who-changed"},
  {"when": {"riskClass": "structural-destructive"}, "then": {"requiredMechanics": {"mustInclude": ["draft-impact-preview-publish", "impact-preview", "danger-zone-type-to-confirm", "org-audit-logged"], "mustNotInclude": ["optimistic-apply", "edit-live-in-place"]}}, "reason": "structural-changes-earn-full-ceremony"},
  {"when": {"multiScopeSetting": true}, "then": {"requiredMechanics": {"mustInclude": ["effective-value-shown", "inherited-from-indicator", "reset-to-inherit"], "mustNotInclude": ["invisible-cascade"]}}, "reason": "a-cascade-must-be-readable"},
  {"when": {"nodeCount": "over-30"}, "then": {"requiredMechanics": {"mustInclude": ["settings-search", "stable-deep-links"]}}, "reason": "search-mandatory-past-thirty-nodes"},
  {"when": {"governedSurfaceLink": true}, "then": {"requiredMechanics": {"mustInclude": ["in-context-gear-bidirectional-link"]}}, "reason": "shadow-product-stays-connected-to-product"},
  {"when": {"subject": "ai-agent-policy"}, "then": {"requiredMechanics": {"mustInclude": ["agent-governance-console", "model-routing-policy", "data-masking-before-llm", "ai-action-audit-view"]}}, "reason": "ai-governance-is-an-org-scope-subject"},
  {"when": {"buildTimeGeneration": true}, "then": {"requiredMechanics": {"mustInclude": ["nl-compiles-to-inspectable-artifact", "edit-before-commit"], "mustNotInclude": ["opaque-black-box"]}}, "reason": "compile-to-the-inspectable-artifact"},
  {"when": {"productSurfaceInTree": true}, "then": {"requiredMechanics": {"mustNotInclude": ["features-hiding-in-settings"]}}, "reason": "product-surfaces-are-not-settings"},
  {"when": {"isSettingsPage": true, "scope": "__absent__"}, "then": {"clarifications": ["setting-scope-unspecified"]}, "reason": "navigate-by-scope-first-so-scope-is-required"}
]}
```
