apps/cli/cordis.yml gains settings-local, credentials-local, and the bare
dormant llm-pi-ai row (manifest deps added for the resolver contract);
llm-deepseek drops its !!js apiKey inline for per-request credential
resolution. Both adapters tag apiKeyEnv role('credential-ref') so the
form mounts the credential control. The web e2e scaffold isolates a
harness home per run — an in-process boot must never touch the
developer's real ~/.dsh — and the new models-settings scenario pins the
whole loop through the shipped app: dormant directory as add vocabulary,
schema-driven editor apply landing in settings.yaml, the route
registering live (topology frame), and a write-only key landing in the
temp .env with the configured badge converging. A hermetic test-owned
reference name keeps a developer's real provider keys from flipping the
badge. schema-form joins the platform module table (seed + externals)
so client bundles share one instance.
The seven behavior-pinning snapshots (workspace-flow, slash-flow,
todo-display, session-title, session-actions, terminal-card,
code-mode-fixture) asserted per-package behavior through the whole
built app: every assertion now lives in the owning package's suite at
equal strength (SlotTestRuntime benches assemble the same plugin apply
over the production slot machinery), while the assembled layer kept
re-failing on unrelated churn at 10s-timeout debugging cost.
What only this lane can prove is the artifact plane: lib/client.js
bundles loading through the ModuleLoader path, staged boot activation
across the inject layers, per-plugin CSS injection, and a journey
reaching chat content over the fixture transport. built-boot.snapshot.ts
pins exactly that, and nothing else — behavior assertions belong to the
package suites.
The Loader resolves each config row against the composing app, so moving the
TUI composition from examples/ into apps/cli left eleven rows unresolvable from
the built bin: `node apps/cli/lib/bin.js` died at boot with "plugin(s) failed to
load". Source-mode runs hid it, because tsconfig paths resolve the whole
workspace regardless of who declares what.
Also declares `dsh-llm-pi-ai` and `dsh-tmux-context`, which a personal
`~/.dsh/config.yaml` inserts to swap the model adapter. Those previously
resolved only because the config lived under examples/, whose package.json
declares the union of every leaf's plugins.
Caught by running the built bin from a scratch directory, which is how a user
actually starts it.