- dsh-host-webserver: the service is HttpServerService under ctx.httpServer
(README said WebServerService/ctx.webServer, matching no symbol in source),
and the dev-mode bundle-watch paragraph described machinery that moved to
dsh-client-modules/dsh-client-hmr in the webserver rewrite — removed; those
packages' READMEs already document the current pipeline.
- dsh-workspace: ctx.workspace.touchSession(id) does not exist; the
activity-pinning chain was replaced by Workspace.insertSessionBefore
(2026-07-25 session-list note) — the bullet now documents the real method.
- packages/storage group table: the domain package directory is
storage-domain/, not domain/.
All three pairs updated on both sides and re-recorded.
- WorkspaceRegistry.archiveSession no longer wraps persistence-listing
failures as WorkspaceUnknownSessionError: only a definite miss (live
lookup, header index, then a fresh list) maps to session-not-found;
storage faults propagate as internal errors, with a negative test.
- The archived-current sweep moves from the unary path into the
projection: any install path (local echo, another tab's frame, a
reconnect baseline) clears a selection that landed in the archive set.
- An archive set installed while workspace.list is in flight supersedes
the stale baseline's set instead of being rolled back by it.
- The workspace-management e2e anchors the archived row by its session
actions button and asserts the single-stray fixture assumption loudly.
- Drop the stale touchSession rows from the workspace READMEs (the
method was removed with its Agent Note).
The workspace domain global singleton gains archivedSessionIds (schema
default [], version unchanged): a display-layer archive set layered over
workspace accounting. archiveSession() rides the registry operation
chain, validates the session against live/persisted headers, and is
idempotent; archived sessions keep their sessionIds slot so a future
unarchive restores position.
- Per-file 100% coverage across the five new packages (invariant
companion suites, failure-injection negatives, lifecycle and
malformed-medium branches).
- Canonical README Model Experience / Known Limitations sections; new
storage/ and workspace/ group READMEs; packages/README.md rows (budget
ceiling raised 760 → 790 for the two new groups).
- Cordis catalog/type-link registrations, service-role classification,
and regenerated catalogs/graphs for the new services and events.
- Agent Note: English body + i18n pairing record; design-sketch fences
opted out of doc-typecheck as ignore-check.
- Two exactOptionalPropertyTypes/discriminant fixes in new tests.
doc-sync (24 gates), typecheck, hygiene, and the five-package suite
(92 tests) all pass.
Review findings applied across the group:
- storage hub: stale disposers no longer remove a successor registration;
the package now default-exports the Storage service class per the
service-package export shape.
- json backend: failed publishes roll back the authoritative memory state
(a rejected write can no longer resurface via get() or ride the next
publish); close() drains in-flight writes and blocks in-flight opens;
double-open rejects as a plain caller error instead of malformed-medium.
- sqlite backend: loadAll builds records on a null prototype (__proto__
keys round-trip instead of polluting), user_version is stamped only
after the schema is fully created, and corrupt record JSON rejects as
malformed-medium instead of a bare SyntaxError.
- domain form: writes persist before mutating authoritative memory or
emitting; DomainChanged is a put/deleted discriminated union.
- workspace: attach/detach idempotence decided on the write chain (stale
snapshots no longer short-circuit), create() requires a directory, and
startup fails loud on duplicate stored paths.
Eleven regression tests pin the fixed behaviors.
ctx.workspace registry owns WorkspaceId-branded records: realpath-
normalized unique paths (create rejects collisions; resolveByPath shares
the normalization), ordered sessionIds as the single source of ownership
truth, attachSession gated on the session header cwd matching the
workspace path (double-booking structurally impossible), dead session
ids filtered on projection and pruned on the next mutate, status()
reporting missing directories. No delete surface this phase — deletion
ships together with the session-side primitives as future work.