Problem
1. Clone derive contradicts design
ApplicationState, ExtensionState::State, and FeatureState::State all #[derive(Clone)]. Cloning ApplicationState propagates through all five domain states, calling Arc::clone on approximately 20–30 shared fields. Each Arc::clone is an atomic fetch_add. The module header explicitly states "Single Source of Truth: All state lives in one place" — but Clone allows an arbitrary number of handles to exist, making ownership opaque.
Files:
Source/ApplicationState/State/ApplicationState.rs
Source/ApplicationState/State/ExtensionState/State.rs
Source/ApplicationState/State/FeatureState/State.rs
2. SCM handle counter in wrong subsystem
FeatureState::State::GetNextSourceControlManagementProviderHandle delegates to self.Markers.GetNextSourceControlManagementProviderHandle(). The SCM provider handle counter lives inside MarkerState, which has no conceptual relationship to Source Control Management providers.
Fix
- Remove
#[derive(Clone)] from ApplicationState, ExtensionState::State, and FeatureState::State.
- Add a type alias:
pub type SharedApplicationState = Arc<ApplicationState>.
- Update all call sites that currently clone state to hold
Arc<ApplicationState> instead.
- Move the SCM provider handle counter out of
MarkerState into a new Arc<AtomicU32> field directly on FeatureState::State, or into a new SCMState sub-module consistent with the existing Debug, Decorations, Diagnostics pattern.
Additional Scope for Same PR
- Verify
ExtensionState::State.ScanReady: Arc<Notify> uses notify_waiters() vs notify_one() correctly at its call site. If multiple concurrent callers await ScanReady at startup (e.g., multiple extension activation tasks), notify_one() would wake only one and leave the rest blocked indefinitely.
Problem
1. Clone derive contradicts design
ApplicationState,ExtensionState::State, andFeatureState::Stateall#[derive(Clone)]. CloningApplicationStatepropagates through all five domain states, callingArc::cloneon approximately 20–30 shared fields. EachArc::cloneis an atomicfetch_add. The module header explicitly states "Single Source of Truth: All state lives in one place" — butCloneallows an arbitrary number of handles to exist, making ownership opaque.Files:
Source/ApplicationState/State/ApplicationState.rsSource/ApplicationState/State/ExtensionState/State.rsSource/ApplicationState/State/FeatureState/State.rs2. SCM handle counter in wrong subsystem
FeatureState::State::GetNextSourceControlManagementProviderHandledelegates toself.Markers.GetNextSourceControlManagementProviderHandle(). The SCM provider handle counter lives insideMarkerState, which has no conceptual relationship to Source Control Management providers.Fix
#[derive(Clone)]fromApplicationState,ExtensionState::State, andFeatureState::State.pub type SharedApplicationState = Arc<ApplicationState>.Arc<ApplicationState>instead.MarkerStateinto a newArc<AtomicU32>field directly onFeatureState::State, or into a newSCMStatesub-module consistent with the existingDebug,Decorations,Diagnosticspattern.Additional Scope for Same PR
ExtensionState::State.ScanReady: Arc<Notify>usesnotify_waiters()vsnotify_one()correctly at its call site. If multiple concurrent callersawaitScanReadyat startup (e.g., multiple extension activation tasks),notify_one()would wake only one and leave the rest blocked indefinitely.