← All config-management frames
Flow 1 · Settings editor · Frame (b) · /config

Provenance, lock, and unset vs pin

The hard part of this UI is not the inputs — it is communicating why a setting has its value and why some settings cannot be changed. Each block below is a distinct EffectiveConfigEntry shape the editor must render differently. Getting these wrong produces a form that lies.

A · source = this scope

An override exists at the scope being edited. This is the only case where "Reset" is meaningful, and it is where the unset-vs-pin distinction bites.

Digest frequency notifications.digest.frequency
Set here · org Acme Corp
A′ · Reset… — two different operations, never one button

These produce the same value today and diverge tomorrow. Collapsing them into a single "Reset to inherited" control is the most likely design error in this flow, and it is silent: nothing looks wrong until the parent changes and the child does or does not follow.

B · source = an ancestor scope, not locked

Editable here — writing creates an override at this scope. The badge names the ancestor; "Inherited" alone does not tell an admin who to talk to.

Batch notifications notifications.digest.enabled
Enabled Inherited from portal Acme Portal
C · locked = true — read-only, and it names the ancestor

The lock owner comes from lockedBy, and the explanation from lockReason. A generic "you cannot edit this" is a design failure: the contract carries exactly who locked it and why, so the UI must say so rather than send the admin hunting.

SMS channel notifications.channel.sms
Disabled Locked by portal Acme Portal

🔒 portal Acme Portal locked this value. lockReason: "SMS is disabled tenant-wide pending carrier review." You are editing org Acme Corp, beneath the lock — the server refuses writes here with LOCKED_BY_ANCESTOR.

D · isReadonly = true — displayed, never editable at any tier

Distinct from a lock: nobody can change it anywhere, so there is no ancestor to name and no "ask your admin" path. Showing this as a lock would misdirect.

Delivery engine notifications.engine.id
readonlysystem
Platform-owned · isReadonly: true
E · this tier is not in allowedScopes

The key exists and resolves, but may not be set here. No input is offered — an enabled control that only fails on save (SCOPE_NOT_ALLOWED) is the failure mode this state exists to prevent.

Tenant sender domain notifications.sender.domain
Inherited from portal Acme Portal
F · no override anywhere — the definition default

Every key resolves to something even with no overrides, because defaultValue is always present. This must not read as "unset/empty" — the value is real and in force.

Max delivery attempts notifications.retry.maxAttempts
Default — never set at any scope

Contract. Every block is one EffectiveConfigEntry: source (a typed Scope — scopeType + scopeId, never a bare id), locked, lockedBy, lockReason, editable, plus definition.isReadonly / definition.allowedScopes. The four reasons a control is disabled — locked, readonly, scope-not-allowed, no Permit grant — are visually distinct, because the user's next action differs in each.

← Settings editor Next: loading, empty, error, hidden-absent →
Review · config-management approve or reject each flow ↓
settings-editorapproved · izzywdev
key-catalogapproved · izzywdev
secret-auditapproved · izzywdev