The merge gives dsh-client-test-runtime the wire-layer edge its sessions
double needs for the session.search result bound; the generated graph records
it. The double's search signature now reads off ISessions instead of naming
RpcResult, so it cannot drift from the contract it implements and needs no
connection-package edge.
Conflict resolutions:
- `session.list`: master's projection columns fold into the PR's cancellable,
batched `listVisibleSessionSummaries`, which `session.search` shares as its
visibility baseline; master's goal helpers stay beside it.
- Client sessions face: master narrowed `ctx.sessions` to `ISessions`, so the
search verb and its protocol-constant bound are declared there and the
test-runtime double implements them (recorded, empty page unless a scenario
stubs hits).
- `WorkspaceBrowser`: master's per-row Rename wiring rides the PR's search
results view; the tree keeps the PR's query-free derivations.
- `dsh web` bin: the PR's shutdown-handlers-before-readiness order with
master's boot-time LAN address snapshot.
- `session-query-sqlite`: master's `SCHEMA_VERSION` 7 stands; the PR's bump
carried no schema change.
- Specs: master wraps assistant/steering message payloads and requires an
`application/json` carrier request, so the search fixtures and tests follow.
- Web aria goldens keep master's recording plus the PR's search placeholder;
the navigation-panes inventory keeps master's terminal-card golden next to
the PR's search-results golden.
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.
Sink the behavior previously held only by the apps/web jsdom snapshots
into the owning packages, each bench mounting the real apply on the
production slot machinery with fixture-fed data:
- ui-conversation/assembly-surfaces: the todo_write turn reaches both
product surfaces (keyed toolview row + dock plan strip via the todos
projection) and the strip follows projection retirement; the keyed
bash row carries its resident terminal card while the fallback row
reaches one through expand; the locked no-session view state; the
composer textarea surviving the blank→active conversion as the same
DOM node; the promptError alert strip with the machine-restored
draft; one summary update re-labeling the breadcrumb.
- ui-workspace/rename-assembly: the session-rename chain (row menu →
dialog → the injected renameSession hop → ISession.rename with the
edge-trimmed draft → dialog close and row re-label from the list),
plus the rejected arm keeping the dialog open with the error.
- runtime/workspaces-service: startInitialSelection — connects the
recent Workspace once both baselines are ready and opens the session,
stays idle with a current session or no recent target (double start
fails loud), and a failed connect returns to waiting and retries on
the next list change.
Component-level arms stay in the existing package suites; these files
prove only the assembled wiring.
The wire-echo stand-in for list-row settlement (title from the rename
unary response, running flips): benches mirror what the production
manager writes into the list store, so row re-label assertions need no
assembled app. Fixture ISession stubs must NOT call it re-entrantly —
they run inside a React event dispatch already wrapped in act, and a
nested act corrupts the global act queue (the next test renders an empty
tree); tests echo from their own top level instead.