Overview
Coclico is architected around an autonomous loop: Observe → Analyze → Act → Validate
- Observe:
DynamicTracerServicecollects CPU/RAM/network telemetry - Analyze:
OptimizationEngineService+SourceAnalyzerService(Roslyn AST) - Act:
AutoPatcherServiceapplies validated patches - Validate:
DigitalTwinServiceensures cyclomatic complexity does not increase
Framework: .NET 10 / C# (LangVersion: preview), UI in WPF + WPF-UI 4.x, DI via Microsoft.Extensions.DependencyInjection.
Startup & DI
Entry point is App.xaml.cs. Startup sequence:
// App.xaml.cs — simplified startup sequence
protected override async void OnStartup(StartupEventArgs e)
{
// 1. Mandatory UAC elevation
if (!ElevationHelper.IsElevated())
ElevationHelper.RestartAsAdmin();
// 2. Build DI container
ServiceContainer.Build(services =>
{
services.AddSingleton<ICacheService, CacheService>();
services.AddSingleton<IDynamicTracer, DynamicTracerService>();
services.AddSingleton<IRollbackService, RollbackService>();
services.AddSingleton<AiChatService>();
services.AddTransient<CleaningService>();
}, validateOnBuild: true);
// 3. SplashWindow during service warm-up
var splash = new SplashWindow();
splash.Show();
await Task.Delay(2000).ConfigureAwait(false);
// 4. Open MainWindow
new MainWindow().Show();
splash.Close();
} ServiceContainer
A thread-safe static wrapper around IServiceProvider. Two main methods:
public static class ServiceContainer
{
/// Mandatory resolution — throws if missing
public static T GetRequired<T>() where T : notnull
=> _provider!.GetRequiredService<T>();
/// Optional resolution — returns null if missing
public static T? GetOptional<T>() where T : class
=> _provider!.GetService<T>();
}
Prefer constructor injection in new code. ServiceContainer.GetRequired<T>() is reserved for cases where injection is impossible (static handlers, WPF converters, etc.).
MVVM Pattern
Coclico strictly follows MVVM with CommunityToolkit.Mvvm 8.4:
- Views (
Views/*.xaml) — pure XAML, no business logic - ViewModels (
ViewModels/*ViewModel.cs) —[ObservableProperty],[RelayCommand] - Services (
Services/*.cs) — business logic, system access, AI
// ViewModels/DashboardViewModel.cs
public partial class DashboardViewModel : ObservableObject
{
[ObservableProperty] private double _cpuUsage;
[ObservableProperty] private long _ramUsedMb;
[RelayCommand]
private async Task RefreshAsync()
{
var snap = await _tracer.GetSnapshotAsync().ConfigureAwait(false);
// Always Dispatcher.InvokeAsync for UI updates
await Application.Current.Dispatcher
.InvokeAsync(() => { CpuUsage = snap.CpuPercent; });
}
} Dual LLM Executor
AiChatService maintains two fully isolated LLamaSharp context/executor pairs to avoid contention between user chat and the optimization engine:
public sealed class AiChatService
{
// Context dedicated to user chat (AiChatView)
private LLamaContext _chatCtx;
private readonly SemaphoreSlim _chatSem = new(1, 1);
// Context dedicated to OptimizationEngine (background)
private LLamaContext _engineCtx;
private readonly SemaphoreSlim _engineSem = new(1, 1);
// Immutable Context Swap — reset without blocking consumers
public async Task ResetChatContextAsync()
{
var old = Interlocked.Exchange(ref _chatCtx, await BuildContextAsync());
old?.Dispose();
}
} FeatureExecutionEngine
All long-running actions must pass through FeatureExecutionEngine.RunFeatureAsync which automatically adds circuit-breaker protection, telemetry, and cancellation support.
RollbackService
Every AI-triggered write operation must be preceded by a rollback snapshot:
// Mandatory pattern before File.WriteAllText
var snapshotId = await _rollback
.CreateSnapshotAsync(targetFilePath)
.ConfigureAwait(false);
try
{
File.WriteAllText(targetFilePath, newContent, Encoding.UTF8);
}
catch
{
await _rollback.RestoreAsync(snapshotId).ConfigureAwait(false);
throw;
} Flow Chains system
Three services manage the automation pipeline lifecycle:
WorkflowPipelineService— CRUD for pipeline definitions (JSON in%APPDATA%\Coclico\flow-chains\)WorkflowPipelineExecutionService— sequential execution with circuit-breaker and security policy enforcementWorkflowExecutionService— high-level orchestration and scheduling
WorkflowPipeline model
public record WorkflowPipeline
{
public Guid Id { get; init; } = Guid.NewGuid();
public string Name { get; init; } = string.Empty;
public List<PipelineNode> Nodes { get; init; } = [];
}
// 28 NodeType values, 10 ConditionOperator values, 3 OnErrorAction values
public enum NodeType
{
KillProcess, LaunchProcess, RestartService, StopService, StartService,
SetRegistryValue, DeleteRegistryKey, CreateDirectory, DeleteFile,
MoveFile, CopyFile, RunScript, CleanTemp, EmptyRecycleBin, FlushDns,
ClearBrowserCache, ClearEventLogs, ClearPrefetch, ClearThumbnailCache,
ClearWindowsErrorReports, FreeRam, SetWorkingSet, PingHost,
DisableNetworkAdapter, EnableNetworkAdapter, Wait, Condition, Log, Notification
} SourceAnalyzer (Roslyn AST) — Phase 3.3
SourceAnalyzerService uses Roslyn to analyze Coclico's own C# source code. It computes per method: Cyclomatic Complexity (CC), Halstead metrics (V, D, E), and Maintainability Index (MI).
Digital Twin Gate — Phase 3.3
Before applying any AI-generated patch, DigitalTwinService validates the patch does not increase cyclomatic complexity. If patchedCC > originalCC, the patch is rejected.
AutoPatcher — Phase 3.4
Manages the AI patch lifecycle with human approval. Default: AutoPatcherAuditOnly = true — patches are logged but never applied without explicit approval via ApproveAndApplyAsync(proposalId).
OptimizationEngine — Phase 2
Runs every 30 seconds in the background. Critical rules: use ArrayPool<byte>.Shared for telemetry buffers, never allocate closures in the main loop, always ConfigureAwait(false).
Security & Audit
SecurityPolicyService merges %APPDATA%\Coclico\security-policy.json with non-suppressible hardcoded defaults. AuditLogService writes append-only NDJSON including AiDecisionContext for full LLM decision traceability.
Code conventions
- Naming:
PascalCasefor classes/interfaces,_camelCasefor private fields,Asyncsuffix for async methods - Injection: Constructor only — never service-locate inside a constructor
- Background:
ConfigureAwait(false)on everyawaitin services - Logging:
LoggingService.LogInfo/LoggingService.LogException— never swallow silently - DTOs: Use
recordfor snapshots and results (immutability) - Secrets: Never hardcode — use
SettingsServiceor environment variables - C# 12: Use primary constructors and collection expressions (
[])