fix: review follow-ups for the session archive set
- 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).
This commit is contained in:
@@ -15,7 +15,7 @@ The session row menu in the sidebar workspace browser carried a purely visual "D
|
||||
- Storage: `archivedSessionIds: z.array(sessionId).default([])`, domain version stays 2 — a purely additive field; pre-field media parse to an empty set through the schema default, no migration code. An archived session keeps its `sessionIds` slot (a future unarchive restores its position), so the set never touches the one-owner accounting invariant.
|
||||
- Registry: `ctx.workspace.archiveSession(id)` rides `enqueueOperation`, serialized with create/delete; a session neither live nor persisted throws `WorkspaceUnknownSessionError`; an already archived id neither writes nor emits. The `archivedSessionIds` getter exposes the read-only set.
|
||||
- RPC: `workspace.archiveSession({sessionId}) → {archivedSessionIds}` (answers the full updated set); the `workspace.list` response carries the set as the reconnect baseline; a new host frame `host/archived-sessions-changed` pushes the full snapshot after every durable change (same posture as `host/workspace-changed`, emitted from the `domain/changed` global-put branch by set comparison). Unknown sessions reuse the `session-not-found` error code.
|
||||
- Client runtime: `WorkspaceListState.archivedSessionIds` (a `ReadonlySet`, reference replaced only on membership change); the list baseline, the unary echo, and the changed frame each install the complete set. `WorkspacesService.archiveSession` calls `sessions.clear()` when the archived session is the current selection, returning to the New Session view (user decision: archiving the open session sends the main view back to the hero).
|
||||
- Client runtime: `WorkspaceListState.archivedSessionIds` (a `ReadonlySet`, reference replaced only on membership change); the list baseline, the unary echo, and the changed frame each install the complete set. the projection sweep clears the current selection whenever it lands in the archive set, returning to the New Session view (user decision: archiving the open session sends the main view back to the hero) — one rule covering the local unary echo, another tab's changed frame, and a reconnect baseline restoring a selection archived while this client was away; a frame or echo landing during an in-flight `workspace.list` also shields the newer set from the stale baseline.
|
||||
- UI: the `delete` menu row (visual-only) becomes `archive` (label "Archive session", non-danger styling, no confirmation dialog — a non-destructive action whose worst misfire is list hiding); filtering is one extra arm in `tree.ts`'s `sessionVisible` predicate, with `deriveGroups`/`deriveFlat` taking an `archived` set parameter so all four surfaces (group loop, stray bucket, search, flat) share one source.
|
||||
|
||||
## Alternatives considered
|
||||
|
||||
Reference in New Issue
Block a user