Deleting the preset a user default names left the setting pointed at an id
nothing will ever supply again, and every session created without an explicit
pick then failed to start — the delete dialog called it 'new sessions cannot
select it', which understates a hard creation error. `remove` now clears the
user layer when it named the preset just deleted, exposing the deployment's own
default underneath. Storing a default that does not exist YET stays deliberate:
the roster is a live directory, so a name absent now may exist by the time a
session asks, and `resolve` still reports that case.
`agentPreset.select` also leaves the loopback set. It was pinned as a real
escalation — one preset mounts the toolset that edits the live runtime — but
`session.create` already takes an `agentPreset`, so pinning only the switch left
the same capability one method over. The deeper reason is that the capability is
not the preset's to grant: the deployment's own default already carries `bash`
and the filesystem tools, so any caller that may start a session at all can
already run commands as this process. `read`/`write`/`remove` stay pinned on
their own footing — those touch files, not sessions.
The lower layer names the preset in the session header; this one moves the
choice to the new-session chip and leaves the header a read-only label, so the
merged goldens carried a label these screens no longer show.
Every changed golden gains only the preset label and the settings row's copy —
78 insertions, no deletions — which is this layer's surface appearing where it
was always going to appear.
Threading a status reader and a patch callback made both call sites long
enough to read as the same code again; handing over the store is one line at
each and says the same thing.
master moved the RPC surface onto the fetch transport, so the two agentPreset
methods arrived there with nothing driving them. Adds the round trip, plus the
two `recompose` edges that had none: an agent that never composed a preset, so
there is nothing to restore, and a restore that fails because the composition
it reaches for is gone — the roster is a live directory.
Marks the deliberate non-Error rejections in the store specs, which is the
branch they exist to cover.
The shared picker's id fallback on both trust levels, the chip refusing an
unrelated settings namespace, a refused `settings.describe`, and a blank
draft that names no source. Drops the picker's `title`, which this layer's
one caller never passes.
The chip renders name and description on two lines with its own icon and
alignment, so it is not the same control as the settings row — the shared
picker carries the row, and the chip keeps its shape.
The settings row and the composer seat differ in where they sit, what they
call the current value, and when they refuse a pick — not in how the picker
behaves. Extracting it also stops the row from reading like the permission
row it has nothing to do with.
Session create and the preset switch can be handed the same two failures, and
a client branching on the code needs them worded identically from either.
Both session upserts write the same eight header columns and differ only in
what they append; the agent_preset column made the pair long enough for the
duplication gate to flag it.
Session create and the preset switch can be handed the same two failures, and
a client branching on the code needs them worded identically from either.
The row and the management section opened `load` the same way — refuse a
concurrent read, mark the store loading, read, fold both refusal shapes into
the store's error. What differs between them starts after that.
The chip and the settings row both spread the same three fields, and
`exactOptionalPropertyTypes` makes the absent-vs-undefined dance verbose
enough that the duplication gate flagged it.