The persistence catalog recognizes SessionEventMap augmentations of
'@deepseek-ai/dsh-session/types' alone, so the selected event's old
root-specifier declaration compiled but silently vanished from the
generated catalog. The hermetic scaffold e2e still addressed the skill
registry as a preset-realm service; under the layered host registry the
composed agent's view is a scope read, and the ambient-root isolation it
proves is unchanged.
The suite composes over the ambient DSH home, so a fixed session id
collides with the log a previous run persisted once the tool-execution
path checks persisted identity.
The shipped-Web e2e enables the bundled badge skill as a stand-in for a
repository plugin's deployment-level provider and asserts the layering both
ways: a standard-preset agent's view merges the global layer with its
preset's local discovery and its loader tool resolves the global skill,
while the host view stays global-only and a core-web agent can read the
layer but composes no loader tool.
This reverts commit f12c131ee9fdbc01b9294c8dc2c73cd36ab717cf.
The layered host skill registry closes the gap the bypass recorded: a
repository plugin's skill root registers into the global layer and reaches
every preset-composed session's catalog, so the fixture declares its skill
root again and the e2e proves the full skill, MCP, and TypeScript
contribution set. The accidental .claude/launch.json from that commit goes
with it.
The skills capability moves back to the host plane as one singleton, layered
with the ScopedLayers infrastructure the tools registry established: a
registration files into its calling context's layer (repository plugins and
host rows land global, a preset's skill-local lands in that preset's layer),
and a read merges the global layer with the viewing scope's chain, the
nearest layer winning duplicate names outright while rank keeps deciding
duplicates within one layer.
The web-app bundle re-enables the base skill registry row (skill-local and
tool-skill stay preset-owned), the standard preset drops its isolate skills
realm for bare rows over the host registry, tool-skill passes the calling
agent as the view scope, and the gateway's skills domain reads the host
registry in the presenter scope — a cold session now resolves its recorded
preset's standing key instead of failing.
Delete design-session citations (decision/audit/plan ordinals, stack
positions), change narration, review choreography, and reviewer-addressed
justification from comments, JSDoc, docs, READMEs, Agent Notes, tests, and
generator templates; restate every affected fact as current-state contract
prose. Fix generated docs at their sources and regenerate the catalogs and
cordis-surface regions; re-paste type-equiv blocks; update every bilingual
counterpart and re-record the pairs. Record the citation rule in the
committed-artifact-citations Agent Note.
The agent plane of this stack's compositions lives behind agent presets,
whose per-preset skills realm has no seam for a deployment-level provider
yet: the fixture's dsh.skills made the prepared wrapper wait forever on a
host skills registry the web/headless profiles no longer compose. Remove
the skill root and its assertions from the fixture and record the gap in
the package's Known Limitations; MCP and entry contributions stay covered
because the tools registry is host-plane and layered.
A hand-damaged preset was silent until the worst moment. An unparsable
composition listed as an ordinary selectable row and failed only at the
next session start — set as default, every new session failed. A
directory whose composition file was deleted vanished from the roster
while still occupying its id: copy answered "delete the existing preset
first" while remove answered "not found", a dead end.
Discovery now owns health: every id-shaped directory is a roster slot,
broken when its composition is missing or unloadable, checked with the
loader's own entryListSchema dialect (!!js included) so health never
rejects what the loader accepts. `broken` rides AgentPreset, the
agentPreset.list entry, and the UI row; mount/recompose/standingKeyFor
refuse broken up front with the discovery-reported reason, while
resolve/read/remove still answer. The section renders marked red cards —
unselectable, uncopyable, deletable, location kept on custom rows — and
both pickers drop broken rows entirely.
The cordis preset's persona now forbids editing the shipped install
(corrupting cordis would disable the mode itself) and points authoring
at $DSH_HOME/.agent-presets; its skill teaches preset.yml metadata, the
copy-first workflow, the one-escalation sandbox reality, and honest
verification. Exercised live: asked to edit the shipped composition the
composed agent refuses citing both rules; asked for real presets (simple
and complex) it lands them under the user root with one approved
escalation each and self-checks with the loader dialect.
Move the triplet to implemented/architecture/, rewrite Proposal into a
present-tense Decision, fold Acceptance criteria and Risks into
Consequences (recording what pins the result), retitle the migration
section to what the move actually touched, and repoint the seven
inbound FIXME/README links.
git mv per the regrouping RFC: the five human-collaboration seams and
tui join packages/interaction/, app-boot becomes packages/boot/, and
jsonrpc joins the renamed scaffold/ (formerly sdk/) as its server half
beside client/protocol/create-sdk/helper/scripts/telemetry, whose
folders drop the legacy sdk- prefix. Three new group README triplets
replace the ui/ and sdk/ ones; tsconfig references/paths/globs,
knip keys, vitest globs, gate scripts, catalogs, docs, and the
lockfile follow. Adds the four settled FIXME rename markers
(dsh-sdk-server, dsh-sdk-telemetry, dsh-sdk-helper, dsh-sdk-scripts).
The scaffold folders diverge from their npm names until those renames
land, so tsconfig.base.json maps the three affected names explicitly
beside the group wildcard. Also repairs two pre-existing stale-path
classes the strengthened sweep surfaced: docs/web-styling.md's retired
web-ui host package and type-model spec fixture-literal joins.
app-boot's three Loader-composition specs time out at the default 5s
under full-suite parallel load on this filesystem (pre-existing;
pass isolated with --testTimeout=30000); interaction/scaffold/boot
suites otherwise green (687 passed).
Copying an existing preset — or drafting one in Creator mode — replaces
the copy-minimal skeleton hint: the creator entry exists now, so the intro
names the two real paths instead of steering everyone at one source.
The settings section gains the conversational authoring entry beside
copying: a dashed add-card (the Models page's affordance) that stages the
self-referential cordis preset and starts a new session on it, closing the
settings panel through the shell's new section owner-prop `close` — the
one shell affordance a section receives, for flows that leave settings.
The seat learns the difference between picking and staging: `select()`'s
immediate apply meets the still-current running session and drops the
stage as unservable, so the entry uses `stage()` and leaves the apply to
the list-change applier that fires when the started session becomes
current. `load()` stops regressing the display when its reply lands after
an applied stage was consumed — staged pick first, then the composition
the current session already carries, then the deployment default.
The authoring lane connects a workspace and drives the gesture to a
composed host session; the section goldens gain the entry.