The live fast-path fence and the raced-collision catch duplicated the same
subagent-ownership classification, tripping the duplication gate. Extract
`fencedLiveAgent` so both paths resolve one live identity through the
fence identically.
The client plugin now consumes `ctx.locale` (dictionary registration plus
the slot `t` seat), but the package graph did not know it: no
`dshClient.inject` entry, no peer/devDependency, no tsconfig project
reference. Mirror the ui-conversation convention so the dependency graph,
HMR/preflight metadata, and standalone packaging all recognize the
`@deepseek-ai/dsh-client-locale` seam.
The raced-collision catch mirrored only the subagent-owned half of
ensureSession's `.catch`: a concurrent plain-agent publish winning the
identity still fell through to `internal`, where ensureSession returns
the winner. Mirror in full — classify a subagent-owned winner as
`agent-busy`, return a clean plain-agent winner directly.
The README claimed "acceptance is governed by registry presence" as a
universal statement, but `sendReport` translates a registered parent's
send rejection into the same PARENT_UNAVAILABLE code — registry presence
governs parent *resolution*, while acceptance additionally depends on the
parent's log still admitting appends. Soften both languages to the
precise contract and re-record the pair.
The `host/session-removed` invalidation flipped the owned catalog and
addressed children to `parentAvailable:false`, but a `subagent.list` pull
already in flight was requested before the removal and its ok-response
carries the pre-removal `parentAvailable:true` — the response then
overwrote both the catalog and every addressed child, resurrecting the
writable-editor-against-a-dead-continuation-owner bug the invalidation
closes, with no refresh scheduled to converge afterwards.
Mark the owner stale when a pull is in flight at removal time, so one
trailing refresh runs after the in-flight response settles and the
post-removal host truth lands. Adds a regression test: removal mid-pull,
stale ok response, trailing pull, final state stays unavailable on the
catalog and the addressed child.
The ui-subagent catalog and read-only composer copy moved from hardcoded
Chinese to the locale-aware `subagent` namespace, so an en-US headless
browser now renders English. The e2e's selectors and goldens still
asserted the old hardcoded Chinese strings, leaving the scenario unable
to find the catalog trigger.
Convert the selectors to the default (en-US) render and re-record the
catalog goldens (ui, tree, nested) in English. The locale-aware parts of
the remaining goldens were already English (recorded under the en-US
default), so sidebar and fork are untouched.
The setup validation and commit moved into the callback, so the outer
definite-assignment slot and its type import are no longer needed; declare
the transaction as a callback-local const.