DSH plugin settings: SettingsNamespace, revisions and writes

Configuration & UsagePublished 2026-10-17Author: DeepSeek Plugin Market
DeepSeek HarnessDSH pluginSettingsNamespacesettings formsrevisionhot commit
How a DSH plugin plugs into settings: namespace equals profile entry id, descriptors carry inherited and override values, and writes split three ways.

A DSH plugin does not build its own settings UI; its Config fields are projected into a form whose key is the profile entry id. That one sentence clears up two common misconceptions: the namespace is not the package name — mount the same package twice with different entry ids and you get two independent forms — and writes are not direct file edits — the settings service validates the full Config, checks the revision, and persists through the config editor as a Cordis patch. Runtime code keeps reading its own Config reference with .get(); the form is another view of the same data.

DSH plugin settings forms: Config projection and namespaces

Bottom line: the settings service projects volatile Config fields of active profile entries; consumers still read their own Config reference.

  1. Projection source: Config fields from active profile entries produce form descriptors.
  2. Namespace rule: the namespace is the entry's local id; different entry ids mean independent forms.
  3. Ordinary fields are excluded: only editable volatile fields appear.
  4. Consumers read values through their own Config reference, not through the settings service.
  5. Persistence path: the config editor writes back through a Cordis patch, so changes land in the profile's patch layer.

DSH plugin settings values: inherited, override, resolved and revision

Bottom line: the descriptor exposes all three values plus a revision, so provenance and conflicts are both visible.

FieldMeaningUse
Inherited valueComposition default not explicitly overriddenShows what the default is
Explicit overrideValue written in the profileShows who changed it
Resolved valueLayered final resultWhat the plugin actually runs with
Optimistic revisionVersion marker from this readPrevents overwrite on write
  1. Diagnose mismatches by comparing resolved with explicit override, then checking where the inherited value came from.
  2. Always carry the revision: omitting expectedRevision writes unconditionally; passing it requires the value you just read.
  3. Stale means rejected: every write validates the full Config and refuses stale revisions before persisting.
  4. Conflict handling: call describe again, merge, then submit with the new revision.

DSH plugin settings writes: update, replace and mutate

Bottom line: edit fields with update, refill a whole section with replace, and use mutate for array paths or redacted secrets.

  1. update(ns, patch, expectedRevision?) merges submitted fields and leaves the rest unchanged.
  2. replace(ns, section, expectedRevision?) resets live fields to inherited config first, then applies the submitted section.
  3. mutate(ns, ops, expectedRevision?) applies path-addressed edits and preserves secret values the client response never contained; unsetting an array index removes the element.
  4. Uniform validation: all three validate the full Config and reject invalid combinations before writing.
  5. Selection rule: when unsure the client holds every field, prefer mutate so redacted empties never get written back.

DSH plugin per-instance page policy: configure and owner scope

Bottom line: configure changes only this instance's presentation policy, never its Config; the owner defaults to the calling fiber.

ts
const dispose = ctx.settings.configure({ auto: true }, owner)
// auto defaults to true; register the disposer with your effects
  1. Presentation only: the policy controls UI behavior such as automatic pages.
  2. One registration per instance: registering twice throws, meaning you configured it in two places.
  3. Explicit owner: pass owner when registering policy for another plugin instance.
  4. Cleanup: register the returned disposer in an effect so the policy disappears on unload.
  5. Native editing: prepareDocument() returns the existing profile patch path for an external editor.

DSH plugin remote reads and redaction: settingsController

Bottom line: the remote namespace sits on settingsController, reads are always redacted, and write refusals split into conflict and rejected.

  1. Reads force redaction: every remote read uses redactSecrets: true, so role('secret') fields never appear.
  2. Writes reuse the semantics: remote writes expose merge, replace and path-addressed operations.
  3. Error classes: provider refusals are classified as settings/conflict or settings/rejected with the service message.
  4. Do not mix the events: settings/document-updated means one entry's form values, availability or page policy changed, so UI re-reads schema, values and revision; use loader/volatile-update only when registration info needs refreshing.
  5. Verify: change a field and confirm settings/document-updated carries a new revision.

DSH plugin settings troubleshooting

Bottom line: split settings problems into wrong value, write rejected and field missing — resolution, revision and schema respectively.

  1. Wrong value — compare inherited, override and resolved values.
  2. Write rejected — check revision staleness and Config validation.
  3. Field missing — confirm it is an editable volatile field.
  4. Secrets wiped — update/replace round-tripped redacted empties; switch to mutate.
  5. Two instances interfering — the namespace must be the entry id, not the package name.
  6. Repair status, stated honestly: the namespace definition, three values, write semantics and remote redaction follow the official Plugin config forms page; confirm ctx.settings and ctx.settingsController signatures against its Cordis API block and your version.

Sources: Plugin config forms, settings service README, LLM streaming and adapter contract.

FAQ

What exactly is a DSH plugin SettingsNamespace, and is it the same as the package name?

A DSH plugin SettingsNamespace is the local id that uniquely locates a profile entry, not the npm package name. When one package is mounted multiple times with different entry ids, each instance gets its own settings form.

What is the difference between the inherited value and the explicit override in a DSH plugin settings descriptor?

A DSH plugin settings descriptor exposes inherited, explicit profile override and resolved values together: the inherited value comes from the composition default, the override is what the profile writes, and the resolved value is the layered result. Those three fields answer where a value came from.

When should a DSH plugin settings write use update, replace or mutate?

DSH plugin settings writes have three semantics: update merges submitted fields, replace resets live fields to inherited config before applying, and mutate edits independent paths while preserving secrets the client never received. Use mutate when round-tripping redacted fields.

Why does a DSH plugin settings write fail with a stale revision?

Every DSH plugin settings write validates the full Config and rejects stale revisions before persisting, preventing one client from overwriting another's change. Re-read with describe to get the new revision instead of retrying the old one.

Are secret fields returned when DSH plugin settings are read remotely?

No: every remote read in DSH plugin settings forces redactSecrets, so a field with a secret role cannot ride the response. Writes use mutate path edits so clients never have to send plaintext secrets back.

Related Terms

SettingsNamespace
SettingsNamespace is the local id that uniquely locates one entry in the current profile and serves as the key of its settings form. Different entry ids mean different plugin instances with separate forms.— https://deepseek-harness.github.io/deepseek-harness/reference/subsystems/settings
SettingsForms
SettingsForms is the service behind ctx.settings: it projects plugin Config schemas into forms and provides description, writes and per-instance page policy. Runtime code still reads configuration through its own Config reference's get().— https://deepseek-harness.github.io/deepseek-harness/reference/subsystems/settings
inherited value
An inherited value in DSH plugin settings is the composition-level default that the profile has not explicitly overridden. It appears alongside the override and resolved values so configuration provenance is visible.— https://deepseek-harness.github.io/deepseek-harness/reference/subsystems/settings
optimistic revision
An optimistic revision is the version marker returned with each settings read and required on write; stale revisions are rejected. It implements optimistic concurrency so two clients cannot silently overwrite each other.— https://deepseek-harness.github.io/deepseek-harness/reference/subsystems/settings

Sources