The per-session scope the host half now reads had no writer. This is it: a
crosshair on the composer tool row, present only in sessions running the facet
preset, opening a panel that sets the focus and the paths allowed outside it.
The gate is the session's own `agentPreset` projection rather than anything
inferred from the URL or from the plugin being installed, so a control for a
plugin that is not running never appears.
It writes through the settings document — the same one the plugin card edits —
because `settings.mutate` accepts a path under a volatile node and refuses
anything else. That is what makes the split real rather than aspirational: the
agent has no write path to `scopes`, and the panel's write is the only one that
can widen a session.
The panel also carries the mode details and the usage notes, which the preset
picker's guide dialog cannot show for a preset no core package ships — its
guide table holds four shipped ids and is looked up only for built-ins.
Also adds `@deepseek-ai/dsh-client-ui-conversation` to the client half's inject
list: registering into `conversation.input.left` is a dependency on the package
that declares it, and `slots.inject` waits for a slot rather than creating one,
so naming another package's slot without loading it first registers nothing —
silently, because nothing errors.
The `volatile()` markers made the Host serve the namespace, and that was as
far as it went: the Plugins page does not build a card from a `Config` schema.
It draws only what browser halves register into the slots it declares, which is
why dsh-slopo, dsh-recall and dsh-context all ship a `client/` — and why this
plugin, with two served fields, still showed nothing.
The card registers into `plugins.bundle.config` while
`configForms.whileServed` reports the namespace served. The two keys are
deliberately different strings and that is the trap in the file: the settings
document is filed under the profile entry id (`facet-policy`) while the card is
keyed by the package name (`dsh-facet`). Every sibling plugin happens to name
them identically. Binding the form to the wrong one yields a card that renders,
saves, and writes nowhere, so `test/client.test.js` pins both, holds the card's
field list to the schema's volatile fields, and refuses to register at all when
the namespace is not served.