Repository navigation
feat: parent and child sessions - #327
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (5)
📒 Files selected for processing (13)
Disabled knowledge base sources:
WalkthroughThe PR adds session provenance and parent/root filters, window instance retargeting, and a shared hierarchical session sidebar. It updates API, storage, CLI, daemon, window-manager, and web session components with tests. ChangesSession lineage and catalog filtering
Window instance retargeting
Hierarchical session navigation UI
Estimated code review effort: 5 (Critical) | ~120 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
| Filename | Overview |
|---|---|
| internal/session/manager_start_storage.go | Extends create-lineage normalization to support provenance-light user sessions while deriving and validating server-owned lineage. |
| internal/store/globaldb/global_db_session_page.go | Applies parent and root lineage filters to durable session catalog queries. |
| internal/windowmanager/reducer_window_navigate.go | Supports replace-mode instance rekeying and resets navigation state during session-window retargeting. |
| web/src/systems/os/lib/routing-coordinator.ts | Coordinates in-place session retargeting while focusing an existing owner window to preserve deduplication. |
| web/src/systems/session/lib/session-hierarchy.ts | Builds provenance trees, retains pagination orphans, flattens thread descendants, and derives collapsed-thread status signals. |
| web/src/systems/session/components/session-sidebar.tsx | Adds the in-window session catalog rail using the shared threaded session-list body. |
Sequence Diagram
sequenceDiagram
participant Caller
participant API as CLI / HTTP / Native Tool
participant Manager as Session Manager
participant Store as Session Store
participant Catalog as Session Catalog
participant Web as Dock / Sidebar
Caller->>API: Create session with explicit or inferred parent
API->>Manager: Create request + parent session ID
Manager->>Store: Resolve parent in target workspace
Store-->>Manager: Parent lineage
Manager->>Manager: Derive root ID and spawn depth
Manager->>Store: Persist user session with provenance
Caller->>Catalog: List by parent or root
Catalog->>Store: Apply workspace and lineage filters
Store-->>Catalog: Matching session tree rows
Catalog-->>Web: Session catalog
Web->>Web: Build provenance threads
Web-->>Caller: Render dock modal or session sidebar
Reviews (2): Last reviewed commit: "fix: review round" | Re-trigger Greptile
| <body> | ||
| <div class="wrap" data-od-id="session-index"> | ||
| <h1>Session domain</h1> | ||
| <p class="sub">Final pages and labs for the session surface. Vocabulary lives in <code>session.css</code>; spec in <code>SESSION-REDESIGN-SPEC.md</code>.</p> |
There was a problem hiding this comment.
Redundant session index subtitle
The paragraph repeats what the self-explanatory heading and linked sections already convey, adding unnecessary descriptive copy to the new index.
| <p class="sub">Final pages and labs for the session surface. Vocabulary lives in <code>session.css</code>; spec in <code>SESSION-REDESIGN-SPEC.md</code>.</p> |
Context Used: CLAUDE.md (source)
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
There was a problem hiding this comment.
Actionable comments posted: 7
🧹 Nitpick comments (2)
web/src/systems/session/hooks/__tests__/use-session-topbar-slot.test.tsx (1)
32-34: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winCover the sidebar-toggle contract.
These fixtures hard-code
sidebarOpentofalseand discardonSidebarToggle. Add a test that supplies both open states, asserts the accessible pressed state, and verifies that clickingsession-sidebar-togglecalls the callback.As per coding guidelines, “Before adding a Vitest or Playwright test, identify the invariant, owning layer, and canonical suite; update existing route, hook, component, story, or E2E suites first.”
Also applies to: 98-99, 139-140
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@web/src/systems/session/hooks/__tests__/use-session-topbar-slot.test.tsx` around lines 32 - 34, Extend the canonical use-session-topbar-slot test suite to cover the sidebar-toggle contract: parameterize or add cases for both sidebarOpen states, assert the session-sidebar-toggle control’s accessible pressed state, and retain an onSidebarToggle spy to verify it is called on click. Update the existing fixture and relevant tests rather than creating a new suite.Source: Coding guidelines
web/src/systems/session/components/session-list/session-list-thread.tsx (1)
76-76: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winUse a tokenized connector offset.
before:left-[11px]introduces an ad-hoc spacing value. Replace it with an exported spacing or layout token.As per coding guidelines, “Use tokens from
packages/ui/src/tokens.cssandDESIGN.mdfor all color, type, radius, spacing, and motion values; do not invent design values.”🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@web/src/systems/session/components/session-list/session-list-thread.tsx` at line 76, Replace the hardcoded before:left-[11px] offset in the session-list thread connector with the appropriate exported spacing or layout token from the established UI tokens, while preserving the connector’s current positioning and appearance.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@internal/api/udsapi/transport_parity_integration_test.go`:
- Around line 1507-1515: Extend the rootQuery assertions in the transport parity
test to issue the same request through HTTP as well as UDS. Compare the HTTP
session catalog IDs and total with the UDS result, preserving the existing
expected whole-tree IDs and using the established transport helper and assertion
patterns from the parent filter checks.
In `@internal/session/manager_start_storage.go`:
- Around line 150-159: The lineage creation flow around
validateCreateLineageReferences must load the derived root session after
resolving rootID and reject it when its WorkspaceID differs from workspaceID.
Preserve the existing parent validation and only persist filled.RootSessionID
after confirming the root belongs to the requested workspace.
In `@internal/windowmanager/reducer_window_navigate.go`:
- Around line 23-25: Move the InstanceKey validation in the window navigation
reducer ahead of the NavigatePop branch so pop commands cannot ignore it. Ensure
any command with InstanceKey set and Mode other than NavigateReplace returns the
existing ErrInvalidCommand, while preserving normal pop handling and
replace-mode behavior.
In `@web/src/systems/os/lib/routing-coordinator.ts`:
- Around line 244-256: The existing-window branch in the routing coordinator
must compare existing.route with target.route before returning from
userActivateWindow. When the routes differ, activate or restore the existing
window, navigate it to target.route, await completion, then call
pushRoute(target.route) exactly once; preserve the current activation-only
behavior for matching routes. Add a regression test covering the same instance
key with different routes.
In `@web/src/systems/session/components/session-list/session-list-thread.tsx`:
- Around line 70-87: Set the child-content container in session-list-thread.tsx
(lines 70-87) to inert whenever collapsed is true, and apply the same change to
the group-content container in session-list-group.tsx (lines 62-82), preventing
keyboard focus while preserving normal interaction when expanded.
In `@web/src/systems/session/components/session-list/session-list.tsx`:
- Around line 77-84: Update the descendant filtering logic in the session-list
thread construction so a matching descendant retains all intermediate ancestors
through the thread root, even when those ancestors do not match the filter.
Preserve the existing root match behavior and ensure childSessions contains the
complete ancestor path rather than only sessions passing matchesFilter.
In `@web/src/systems/session/lib/session-hierarchy.ts`:
- Around line 20-30: Update the session hierarchy construction around the
parentId and childrenByParent logic to detect multi-session lineage cycles, not
just self-parenting. Before nesting a session, identify cycles such as A → B → A
and place every participant in the cycle into roots so SessionList can render
them; preserve normal parent-child nesting for acyclic sessions. Add coverage
for a two-session cycle.
---
Nitpick comments:
In `@web/src/systems/session/components/session-list/session-list-thread.tsx`:
- Line 76: Replace the hardcoded before:left-[11px] offset in the session-list
thread connector with the appropriate exported spacing or layout token from the
established UI tokens, while preserving the connector’s current positioning and
appearance.
In `@web/src/systems/session/hooks/__tests__/use-session-topbar-slot.test.tsx`:
- Around line 32-34: Extend the canonical use-session-topbar-slot test suite to
cover the sidebar-toggle contract: parameterize or add cases for both
sidebarOpen states, assert the session-sidebar-toggle control’s accessible
pressed state, and retain an onSidebarToggle spy to verify it is called on
click. Update the existing fixture and relevant tests rather than creating a new
suite.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: a57881ed-ec3d-4c31-bdc8-61a3dd3e4dc7
⛔ Files ignored due to path filters (20)
docs/design/opendesign/README.mdis excluded by!docs/design/**/*,!**/*.mddocs/design/opendesign/session/SESSION-REDESIGN-SPEC.mdis excluded by!docs/design/**/*,!**/*.mddocs/design/opendesign/session/index.htmlis excluded by!docs/design/**/*docs/design/opendesign/session/index.html.artifact.jsonis excluded by!docs/design/**/*,!**/*.jsondocs/design/opendesign/session/session-sidebar.htmlis excluded by!docs/design/**/*docs/design/opendesign/session/session-sidebar.html.artifact.jsonis excluded by!docs/design/**/*,!**/*.jsondocs/qa/scenarios/ET-web-session-inspector-toggle.mdis excluded by!**/*.mddocs/qa/scenarios/ET-web-session-sidebar-threads.mdis excluded by!**/*.mddocs/qa/scenarios/ET-web-session-thread-full-bleed.mdis excluded by!**/*.mddocs/qa/scenarios/ET-web-sessions-catalog-modal.mdis excluded by!**/*.mddocs/qa/scenarios/RT-session-parent-provenance.mdis excluded by!**/*.mdinternal/tools/builtin/testdata/native-tool-catalog.jsonis excluded by!**/*.jsonopenapi/compozy.jsonis excluded by!**/*.jsonpackages/site/content/docs/cli/session/list.mdxis excluded by!**/*.mdxpackages/site/content/docs/cli/session/new.mdxis excluded by!**/*.mdxpackages/site/content/docs/sessions/lifecycle.mdxis excluded by!**/*.mdxskills/compozy/references/native-tools.mdis excluded by!**/*.mdskills/compozy/references/runtime-operations.mdis excluded by!**/*.mdweb/src/generated/compozy-openapi.d.tsis excluded by!**/generated/**,!**/generated/**,!**/*.d.tsweb/src/systems/session/components/stories/session-sidebar.stories.tsxis excluded by!**/*.stories.tsx
📒 Files selected for processing (53)
internal/api/contract/session_runtime_payloads.gointernal/api/contract/windowmanager_command_payloads.gointernal/api/core/agent_identity.gointernal/api/core/handlers.gointernal/api/core/session_catalog.gointernal/api/spec/session_catalog.gointernal/api/udsapi/transport_parity_integration_test.gointernal/cli/client_test.gointernal/cli/session_catalog_client.gointernal/cli/session_create.gointernal/cli/session_list.gointernal/daemon/native_session_list.gointernal/daemon/native_session_mutation.gointernal/daemon/native_tools_test.gointernal/daemon/spawn_reaper_test.gointernal/session/catalog_page.gointernal/session/manager_create_prepare.gointernal/session/manager_lineage_test.gointernal/session/manager_start_storage.gointernal/session/query_test.gointernal/store/globaldb/global_db_session_index_test.gointernal/store/globaldb/global_db_session_page.gointernal/store/session_catalog_page.gointernal/tools/builtin/sessions.gointernal/windowmanager/commands.gointernal/windowmanager/lifecycle_test.gointernal/windowmanager/reducer_window_navigate.goweb/src/systems/os/apps/session/session-window-content.tsxweb/src/systems/os/apps/session/session-window-view.tsxweb/src/systems/os/apps/session/session-window.tsxweb/src/systems/os/apps/session/use-session-window-controller.tsxweb/src/systems/os/apps/session/use-session-window-sidebar.tsweb/src/systems/os/components/__tests__/sessions-modal.test.tsxweb/src/systems/os/components/sessions-modal.tsxweb/src/systems/os/components/stories/_shell-fixture.tsxweb/src/systems/os/hooks/__tests__/os-interaction-hooks.test.tsxweb/src/systems/os/hooks/__tests__/use-os-window-deck.test.tsxweb/src/systems/os/lib/__tests__/routing-coordinator.test.tsweb/src/systems/os/lib/os-types.tsweb/src/systems/os/lib/routing-coordinator.tsweb/src/systems/os/runtime/window-manager-tab-commands.tsweb/src/systems/session/components/session-list/session-list-archived.tsxweb/src/systems/session/components/session-list/session-list-group.tsxweb/src/systems/session/components/session-list/session-list-row.tsxweb/src/systems/session/components/session-list/session-list-thread.tsxweb/src/systems/session/components/session-list/session-list.tsxweb/src/systems/session/components/session-sidebar.tsxweb/src/systems/session/hooks/__tests__/use-session-topbar-slot.test.tsxweb/src/systems/session/hooks/use-session-sidebar-state.tsweb/src/systems/session/hooks/use-session-topbar-slot.tsxweb/src/systems/session/index.tsweb/src/systems/session/lib/__tests__/session-hierarchy.test.tsweb/src/systems/session/lib/session-hierarchy.ts
| parentLineage := store.NormalizeSessionLineage(parent.ID, parent.Lineage) | ||
| rootID := strings.TrimSpace(parentLineage.RootSessionID) | ||
| if rootID == "" { | ||
| rootID = parent.ID | ||
| } | ||
| filled := *lineage | ||
| filled.ParentSessionID = parentID | ||
| filled.RootSessionID = rootID | ||
| filled.SpawnDepth = parentLineage.SpawnDepth + 1 | ||
| return &filled, nil |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Validate the derived root workspace before persisting lineage.
The code verifies that parent belongs to workspaceID, but it does not verify the derived root. validateCreateLineageReferences only verifies that the root exists.
If a same-workspace parent has a root reference in another workspace, this code persists that foreign root on the new session. Load the root and reject it when its WorkspaceID differs from workspaceID.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@internal/session/manager_start_storage.go` around lines 150 - 159, The
lineage creation flow around validateCreateLineageReferences must load the
derived root session after resolving rootID and reject it when its WorkspaceID
differs from workspaceID. Preserve the existing parent validation and only
persist filled.RootSessionID after confirming the root belongs to the requested
workspace.
| const parentId = session.lineage?.parent_session_id ?? ""; | ||
| if (parentId !== "" && parentId !== session.id && byId.has(parentId)) { | ||
| const siblings = childrenByParent.get(parentId); | ||
| if (siblings) { | ||
| siblings.push(session); | ||
| } else { | ||
| childrenByParent.set(parentId, [session]); | ||
| } | ||
| continue; | ||
| } | ||
| roots.push(session); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Handle multi-session lineage cycles.
The self-parent check does not handle A -> B -> A cycles. Both sessions enter childrenByParent, roots stays empty, and SessionList renders neither session.
Detect parent cycles before nesting. Keep each cycle participant visible as a root. Add coverage for a two-session cycle.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@web/src/systems/session/lib/session-hierarchy.ts` around lines 20 - 30,
Update the session hierarchy construction around the parentId and
childrenByParent logic to detect multi-session lineage cycles, not just
self-parenting. Before nesting a session, identify cycles such as A → B → A and
place every participant in the cycle into roots so SessionList can render them;
preserve normal parent-child nesting for acyclic sessions. Add coverage for a
two-session cycle.
|
React Doctor found no new issues. 🎉 Reviewed by React Doctor for commit |
Session sidebar + parent-session provenance
Implements
docs/design/opendesign/session/session-sidebar.html: the session window grows an in-window sessions rail hosting the same catalog body the dock's Sessions surface uses, and sessions created from inside another session now record that origin as queryable lineage — rendered as nested "provenance threads" in both the sidebar and the dock modal.The prototype proposed a new
session.parent_idbackend field. Recon showed the field already ships as part of the safe-spawn lineage record (lineage.parent_session_id/root_session_id/spawn_depth, migrated and indexed insessionssince the safe-spawn work), so this PR adds no schema migration. The real gaps were: (1) the everyday agent path (compozy__session_create) dropped the caller's identity on the floor, (2) validation forbade a parent on non-spawnedsessions, (3) no read-side filters existed, and (4) nothing in the web rendered the hierarchy.Demo
session-sidebar-demo.mp4
Product decisions (locked before implementation)
parent_session_id/root_session_id/spawn_depthbut staystype: "user"— no TTL, no auto-stop, no spawn budget, no permission narrowing. Governed children still come exclusively fromcompozy spawn/POST /api/agent/spawn, whose semantics are untouched.localStorage compozy:session:sidebar:v1.parent=/root=on the catalog across HTTP, UDS, CLI, and the native tool.Invariants resolved during implementation: provenance links never cross the workspace boundary (explicit cross-workspace parent → validation error; native-tool cross-workspace create stays unlinked); the spawn reaper never touches
user-type sessions regardless of lineage; depth chains server-side (depth = parent.depth + 1, root inherited); lineage is immutable post-create, so cycles are impossible.Backend
Provenance lineage on the create path
internal/session/manager_start_storage.go—normalizeCreateLineagenow accepts a parent onusersessions (rule was "only spawned may have a parent"; now "spawned or user"). NewprepareProvenanceLineageresolves the parent once, enforces same-workspace, and fills server-ownedroot_session_id/spawn_depthfrom the parent's tree — caller-supplied root/depth are overwritten, so they can't be forged.validateProvenanceLineageShaperejects any governance field (TTL, auto-stop, spawn role, budget, permission policy) on a provenance link withErrValidation.ErrSessionNotFound(→ 404); shape/workspace violations map to 400. Coordinator/system/dream sessions still cannot carry a parent.Creation surfaces
internal/daemon/native_session_mutation.go):compozy__session_createlinksscope.SessionID— the hosted-MCP-bound, nonce+PID-validated caller — as parent whenever the target workspace equals the caller's. Not a tool input, so an agent can neither forge nor suppress it. Cross-workspace creates (reachable only under approve-all permission mode; the registry denies them by default) stay unlinked rather than failing, preserving the existing capability.internal/api/contract,internal/api/core/handlers.go):CreateSessionRequest.parent_session_id; when absent andX-Compozy-Session-ID/X-Compozy-Agentheaders resolve to a valid active caller, the caller becomes the parent. Invalid claimed identity fails the create (401/403) instead of silently proceeding.internal/cli/session_create.go):compozy session new --parent <id>.Catalog read side
parent=(direct children) androot=(whole tree, root row included — roots storeroot_session_id = own id) filters threaded throughsession.ListQuery→store.SessionCatalogPageQuery→ SQL clauses, plus the active-row matcher, with both filters bound into the list-cursor fingerprint so cursors can't be replayed across queries.GET /api/sessions(HTTP+UDS, OpenAPI spec updated),compozy session list --parent/--root, and thecompozy__session_listinput schema (descriptor digest regenerated). The CLI human/toon table gains aParentcolumn;-o json/-o jsonlalready carried full lineage.Window-manager retarget (daemon)
NavigateWindowCommandgains an optionalinstance_key(internal/windowmanager/commands.go, contract payload + strict decode). The reducer applies it on replace-mode only (push+retarget isErrInvalidCommand), re-keys the window, and resets the nav stack — a stale cross-instance back-stack would otherwise let a breadcrumb pop resurrect a duplicate window for a session that moved elsewhere.Web
Shared session list with provenance threads
SessionsModalBody(previously module-private insidesessions-modal.tsx) is extracted intoweb/src/systems/session/components/session-list/— one file per responsibility (session-list.tsx,-row,-thread,-group,-archived) — and the dock modal becomes a thin Dialog wrapper around it. The modal and the new sidebar render the exact same body, so nesting shipped in both for free.lib/session-hierarchy.ts(ported from the tasks subtask tree):buildSessionTreenests a session under its loaded parent and keeps orphans as roots so nothing vanishes behind pagination;collectThreadSessionsflattens deep chains into their root's thread (one visual nesting level, per the design grammar);childSessionSignalTonesurfaces the most urgent child state (failed > waiting > running) on a collapsed thread's toggle so escalations never hide behind the fold.aria-current. One deliberate delta: the chip lives in the row's trailing action cluster rather than inside the row button — the prototype nested arole="button"inside a<button>, which violates the accessibility floor.The sidebar
SessionSidebar(session system, presentational): 264 px left rail on the window's rail surface, filter + Recent ⇄ All panes + agent groups + "New session" footer (wired to the existing create flow). Width-animated open/close honoringmotion-reduce,inertwhile closed so keyboard order skips hidden content.SquareTerminal) so it doesn't read as a twin of the inspector'sPanelRight. Open preference is one global flag; per-thread collapse is shared with the dock modal (both from the persisted@xstate/storeatcompozy:session:sidebar:v1, cross-tab synced — same pattern as the inspector store).useSessionswith the same filters), so the rail is cache-warm on first open and live through the existingsession_catalog_changedstream — no new SSE connection.In-place switch with dedup
RoutingCoordinator.userRetarget(the only URL↔WM bridge): if the target instance already owns a live window →userActivateWindow(focus, one history push); otherwiseWindowManagerRuntime.retargetWindowdispatches the extendedwindow.navigateand one history entry follows.SessionWindowderives its session from the window route, so the retargeted window re-renders onto the new session with the prompt runtime remounting via the existingkey={id}.Cross-surface
skills/compozy/references/):runtime-operations.mddocuments provenance semantics +parent/rootcatalog queries;native-tools.mddocuments the auto-link onsession_createand the newsession_listinputs.packages/site/content/docs/sessions/lifecycle.mdxgains a "Creation provenance" section (provenance vs governed spawn, all three recording paths, filters); CLI reference pages regenerated viamake codegen.session/added to the opendesign README index;SESSION-REDESIGN-SPEC.mdgains a §12 addendum recording shipped decisions and authorized deltas vs the prototype.RT-session-parent-provenanceandET-web-session-sidebar-threads;ET-web-sessions-catalog-modal,ET-web-session-thread-full-bleed,ET-web-session-inspector-togglereset and re-walked.Compozy Impact Audit
compozy__session_listinput schema gainsparent/root(descriptor digest +native-tool-catalog.jsonregenerated);compozy__session_createbehavior documented (auto-link, not an input — schema unchanged); catalog testdata co-shipped.sessions.createkeepsSessionTypeSystemwith no caller session — checked, no impact. WM command protocol extended (window.navigate.instance_key), strict-decoded.parent/rootfilters compose with the existing workspace scoping; list-cursor fingerprints bind the new filters. Payloads already carried lineage — no new cross-workspace read path.runtime-operations.md,native-tools.md).Verification
manager_lineage_test.go(provenance rules, governance rejection, cross-workspace, chaining),query_test.go+global_db_session_index_test.go(lineage filters, active + durable layers),spawn_reaper_test.go(provenance sessions never reaped),native_tools_test.go(bound-scope auto-link, operator stays unlinked),lifecycle_test.go(retarget re-keys + resets nav stack; push+retarget rejected), plus a provenance leg added to the UDS↔HTTP transport-parity integration suite (explicit + identity-inferred create, filter parity across transports). Touched packages green under-race(~7.3k tests).session-hierarchyunit suite; sessions-modal suite extended with nesting + thread-integrity-filter cases; routing-coordinator suite extended with retarget + dedup cases; full web lane green (538 files / 4366 tests),make bun-lint+ typecheck clean; new Storybook storysystems/session/components/SessionSidebar(threads + collapsed-signal variants).make codegenco-shipped (openapi/compozy.json,web/src/generated/compozy-openapi.d.ts, tool catalog, CLI docs);make codegen-checkclean.eng-qa-bootstrap, teardownclean: true):RT-session-parent-provenancewalked over real CLI/HTTP — explicit parent, depth chaining, filters, Parent column, missing-parent and cross-workspace rejections, identity-header inference.ET-web-session-sidebar-threads+ the three reset web scenarios walked in the browser against the lab daemon — closed default, 264 px rail, thread chip with 5 nested children, collapse/expand, in-place switch (URL moved, one window), dedup focus (no duplicate window), persistence across reload, modal sharing the same threads, prototype-vs-implementation capture bundle with zero unresolved structural mismatches. All five scenarios recordedpasswith evidence in the lab journey log.🤖 Generated with Claude Code
Summary by CodeRabbit