Skip to content

Stable identity, stale-event rejection, and scoped notifications - #154

Closed
IeuanWalker wants to merge 10 commits into
mainfrom
Phase10
Closed

Stable identity, stale-event rejection, and scoped notifications#154
IeuanWalker wants to merge 10 commits into
mainfrom
Phase10

Conversation

@IeuanWalker

Copy link
Copy Markdown
Owner

No description provided.

@IeuanWalker
IeuanWalker requested a review from Copilot July 23, 2026 01:06
@IeuanWalker
IeuanWalker marked this pull request as ready for review July 23, 2026 01:07

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Not ready to approve

The new conversation snapshot helpers re-lock a System.Threading.Lock that is already held in multiple call sites, which can lead to self-deadlock and should be corrected before merging.

Pull request overview

This PR refactors session state to separate lifecycle/run-state from UI-visible “blocking” statuses, centralizes pending-interaction bookkeeping, and introduces reusable session-status presentation for the UI so status rendering is consistent across header and session list.

Changes:

  • Introduces grouped session state (Lifecycle, Conversation, Ui, PendingInteractions) and projects a UI-facing DisplayStatus from run state + pending interactions.
  • Adds SessionInteractionCoordinator and updates permission/user-input/elicitation features to use it for consistent cross-type pending interaction behavior.
  • Updates UI components to use the new state surfaces and consolidates status rendering via SessionStatusBadge + SessionStatusPresentation, plus adds targeted unit tests for the new primitives.
File summaries
File Description
Tests/Cockpit.UnitTests/Features/UserInputRequests/UserInputFeatureTests.cs Updates tests to validate run-state vs display-status behavior and new pending-interaction storage.
Tests/Cockpit.UnitTests/Features/Update/UpdateFeatureTests.cs Updates “active session” checks to use lifecycle run state.
Tests/Cockpit.UnitTests/Features/Sessions/SessionUiStateTests.cs Adds tests for per-session UI-scoped state forwarding and isolation.
Tests/Cockpit.UnitTests/Features/Sessions/SessionStatusBehaviourTests.cs Adds tests for status presentation and concurrent interaction-type status transitions.
Tests/Cockpit.UnitTests/Features/Sessions/SessionListFeatureTests.cs Updates session creation in tests to use lifecycle run state.
Tests/Cockpit.UnitTests/Features/Sessions/SessionLifecycleStateTests.cs Adds tests for lifecycle transitions, stale transition rejection, and reset semantics.
Tests/Cockpit.UnitTests/Features/Sessions/SessionInteractionCoordinatorTests.cs Adds tests for coordinator behavior (duplicates, notifications, resolution order, run-state reveal).
Tests/Cockpit.UnitTests/Features/Sessions/SessionConversationStateTests.cs Adds tests for snapshot stability, message replacement/capacity behavior, and compatibility surface.
Tests/Cockpit.UnitTests/Features/SessionEvents/SessionEventProcessorTests.cs Updates tests to set lifecycle run state rather than UI status.
Tests/Cockpit.UnitTests/Features/SessionEvents/Handlers/SessionShutdownHandlerTests.cs Updates shutdown handler tests to set lifecycle run state.
Tests/Cockpit.UnitTests/Features/SessionEvents/Handlers/SessionIdleHandlerTests.cs Updates idle handler tests to set lifecycle run state.
Tests/Cockpit.UnitTests/Features/Permissions/PermissionFeatureTests.cs Updates tests for new lifecycle run-state property and revised comments.
Tests/Cockpit.UnitTests/Features/Models/ModelFeatureTests.cs Updates tests to use lifecycle run state.
Tests/Cockpit.UnitTests/Features/ElicitationRequests/ElicitationFeatureTests.cs Updates tests to use interaction coordinator + lifecycle run state and new pending-interaction store.
Tests/Cockpit.UnitTests/Features/Agents/AgentFeatureTests.cs Updates tests to use lifecycle run state.
Tests/Cockpit.Benchmarks/SessionLoadingBenchmarks.cs Updates benchmark session creation to use lifecycle run state.
src/Cockpit/MauiProgram.cs Registers SessionInteractionCoordinator in DI.
src/Cockpit/Features/UserInputRequests/UserInputFeature.cs Routes session bookkeeping through SessionInteractionCoordinator instead of direct status/history mutation.
src/Cockpit/Features/Updates/UpdateFeature.cs Treats “active session” as lifecycle run-state running (not blocked UI status).
src/Cockpit/Features/Sessions/SessionFeature.SdkConfiguration.cs Extracts system-message customization helpers into a dedicated partial file.
src/Cockpit/Features/Sessions/SessionFeature.Replay.cs Extracts replay helper into a dedicated partial file and updates to conversation snapshot API.
src/Cockpit/Features/Sessions/SessionFeature.Reconnect.cs Uses lifecycle SDK state transitions and clears pending interaction bookkeeping via coordinator on reconnect.
src/Cockpit/Features/Sessions/SessionFeature.Messages.cs Uses lifecycle change-version capture/clear and conversation snapshot publishing for message sends/retries.
src/Cockpit/Features/Sessions/SessionFeature.Loading.cs Reworks session load to use lifecycle transition tokens and conversation state APIs; adds context replay isolation.
src/Cockpit/Features/Sessions/SessionFeature.Lifecycle.cs Removes large blocks moved to new partial files; updates remaining lifecycle-related logic to use Lifecycle.
src/Cockpit/Features/Sessions/SessionFeature.Eviction.cs Uses lifecycle reset + conversation clearing and coordinator bookkeeping clear during eviction.
src/Cockpit/Features/Sessions/SessionFeature.Discovery.cs Extracts existing-session discovery/metadata materialization into a dedicated partial file.
src/Cockpit/Features/Sessions/SessionFeature.cs Updates event processing and “working” detection to use conversation/lifecycle grouped state.
src/Cockpit/Features/Sessions/SessionFeature.Creation.cs Extracts session creation into a dedicated partial file and initializes lifecycle state.
src/Cockpit/Features/Sessions/Models/SessionUiState.cs Adds a dedicated container for UI-owned, transient per-session state.
src/Cockpit/Features/Sessions/Models/SessionStatusEnum.cs Re-documents status as UI-facing projection rather than lifecycle.
src/Cockpit/Features/Sessions/Models/SessionModel.UiCompatibility.cs Adds compatibility properties mapping legacy callers to Ui.
src/Cockpit/Features/Sessions/Models/SessionModel.LifecycleCompatibility.cs Adds compatibility properties mapping legacy callers to Lifecycle.
src/Cockpit/Features/Sessions/Models/SessionModel.cs Converts SessionModel to partial and introduces grouped state + computed DisplayStatus.
src/Cockpit/Features/Sessions/Models/SessionModel.ConversationCompatibility.cs Adds compatibility properties mapping legacy callers to Conversation.
src/Cockpit/Features/Sessions/Models/SessionLifecycleState.cs Introduces lifecycle state object with versioned transitions and pending-change capture/clear.
src/Cockpit/Features/Sessions/Models/SessionConversationState.cs Introduces conversation state object with published immutable message snapshots.
src/Cockpit/Features/Sessions/Models/AgentRunStateEnum.cs Adds lifecycle run-state enum independent of pending interactions.
src/Cockpit/Features/Sessions/Interactions/SessionInteractionCoordinator.cs Adds coordinator for consistent pending interaction bookkeeping and display-status overlay.
src/Cockpit/Features/Sessions/Interactions/PendingInteractionState.cs Adds per-session pending interaction collections + display status storage.
src/Cockpit/Features/SessionEvents/SessionEventProcessor.cs Writes lifecycle run state instead of UI status in reconnect-continuation handling.
src/Cockpit/Features/SessionEvents/Handlers/UserMessageHandler.cs Writes lifecycle run state on user message handling.
src/Cockpit/Features/SessionEvents/Handlers/ThinkingExhaustedContinuationHandler.cs Writes lifecycle run state on continuation handling.
src/Cockpit/Features/SessionEvents/Handlers/SessionIdleHandler.cs Writes lifecycle run state on idle transitions and reads suppression flag from lifecycle.
src/Cockpit/Features/SessionEvents/Handlers/SessionErrorHandler.cs Writes lifecycle run state on error transitions.
src/Cockpit/Features/SessionEvents/Handlers/AssistantTurnStartHandler.cs Writes lifecycle run state on turn start.
src/Cockpit/Features/Permissions/PermissionFeature.cs Routes pending permission bookkeeping through coordinator; reads YOLO from Ui.
src/Cockpit/Features/Models/ModelFeature.Persistence.cs Marks model-change via lifecycle pending-change versioning instead of boolean flags.
src/Cockpit/Features/ElicitationRequests/ElicitationFeature.cs Routes pending elicitation bookkeeping through coordinator.
src/Cockpit/Components/Pages/SessionsPanel/SessionListItem.razor.css Removes now-redundant per-item status color rules (moved to badge component).
src/Cockpit/Components/Pages/SessionsPanel/SessionListItem.razor.cs Removes status-class helper (replaced by shared badge component).
src/Cockpit/Components/Pages/SessionsPanel/SessionListItem.razor Uses SessionStatusBadge and lifecycle SDK state for loading overlay.
src/Cockpit/Components/Pages/ContextPanel/TokenUsagePanel.razor.cs Uses lifecycle run state for compaction disable/tooltip logic.
src/Cockpit/Components/Pages/ChatPanel/UserInputRequest/UserInputRequestPanel.razor.cs Reads/writes user response text from Ui and pulls requests from PendingInteractions.
src/Cockpit/Components/Pages/ChatPanel/Permissions/PermissionRequestPanel.razor.cs Pulls permission requests from PendingInteractions.
src/Cockpit/Components/Pages/ChatPanel/InputArea/SessionModeControl.razor.cs Marks agent-mode change via lifecycle versioning.
src/Cockpit/Components/Pages/ChatPanel/InputArea/SessionModeControl.razor Disables mode changes using DisplayStatus + pending permission interactions.
src/Cockpit/Components/Pages/ChatPanel/InputArea/ModelControl.razor.cs Marks model changes via lifecycle versioning.
src/Cockpit/Components/Pages/ChatPanel/InputArea/ModelControl.razor Disables model/reasoning changes using DisplayStatus and pending permissions.
src/Cockpit/Components/Pages/ChatPanel/InputArea/ChatInputArea.razor.cs Uses Ui for draft/attachments/YOLO and PendingInteractions for input disablement.
src/Cockpit/Components/Pages/ChatPanel/InputArea/ChatInputArea.razor Uses PendingInteractions and Ui.IsYolo for UI gating and button state.
src/Cockpit/Components/Pages/ChatPanel/InputArea/AttachmentsControl.razor.cs Reads/writes attachments from Ui.PendingAttachments with Ui.PendingAttachmentsLock.
src/Cockpit/Components/Pages/ChatPanel/InputArea/AgentControl.razor.cs Marks agent changes via lifecycle versioning.
src/Cockpit/Components/Pages/ChatPanel/InputArea/AgentControl.razor Disables agent changes using DisplayStatus + pending permissions.
src/Cockpit/Components/Pages/ChatPanel/ElicitationRequest/ElicitationRequestPanel.razor.cs Pulls elicitation requests from PendingInteractions.
src/Cockpit/Components/Pages/ChatPanel/ChatPanel.razor.cs Tracks message counts using conversation snapshots and toggles terminal state via Ui.
src/Cockpit/Components/Pages/ChatPanel/ChatPanel.razor Uses SessionStatusBadge for header status and Ui.IsTerminalOpen for terminal toggle.
src/Cockpit/Components/Pages/ChatPanel/ChatMessages.razor.cs Uses conversation snapshots to decide initial scroll behavior.
src/Cockpit/Components/Pages/ChatPanel/ChatMessages.razor Renders from conversation snapshot rather than mutable message list.
src/Cockpit/Components/Controls/SessionStatusVariant.cs Adds display variants for the shared status badge.
src/Cockpit/Components/Controls/SessionStatusPresentation.cs Centralizes status-to-text/class mapping for consistent UI rendering.
src/Cockpit/Components/Controls/SessionStatusBadge.razor.css Consolidates header/list status styling into the badge component.
src/Cockpit/Components/Controls/SessionStatusBadge.razor Adds shared component for session status display in header and session list.

Review details

  • Files reviewed: 73/73 changed files
  • Comments generated: 1
  • Review effort level: Low

Note

Your feedback helps us improve the quality of this feature.
Please use 👍 or 👎 to tell us whether this assessment is correct.

Comment on lines +22 to +32
/// <summary>
/// Publishes the current mutable message collection as an immutable render snapshot.
/// Existing callers may already hold <see cref="SyncRoot"/>; the lock is re-entrant.
/// </summary>
internal void PublishMessagesSnapshot()
{
lock(SyncRoot)
{
MessagesSnapshot = [.. _messages];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants