1use std::fmt::Write as _;
2
3pub struct Recipe {
4 pub severity: &'static str,
5 pub title: &'static str,
6 pub steps: &'static [&'static str],
7 pub dig_deeper: Option<&'static str>,
8}
9
10struct RecipeAc {
11 ac: aho_corasick::AhoCorasick,
12 recipe_indices: Vec<usize>,
13}
14
15static RECIPE_AC: std::sync::OnceLock<RecipeAc> = std::sync::OnceLock::new();
16
17fn recipe_ac() -> &'static RecipeAc {
18 RECIPE_AC.get_or_init(|| {
19 let total: usize = ALL_RECIPES.iter().map(|e| e.triggers.len()).sum();
20 let mut patterns: Vec<&str> = Vec::with_capacity(total);
21 let mut recipe_indices: Vec<usize> = Vec::with_capacity(total);
22 for (i, entry) in ALL_RECIPES.iter().enumerate() {
23 for &trigger in entry.triggers {
24 patterns.push(trigger);
25 recipe_indices.push(i);
26 }
27 }
28 RecipeAc {
29 ac: aho_corasick::AhoCorasick::new(&patterns).expect("valid patterns"),
30 recipe_indices,
31 }
32 })
33}
34
35pub fn match_recipes(output: &str) -> Vec<&'static Recipe> {
36 let lower = output.to_ascii_lowercase();
37 let state = recipe_ac();
38 let mut seen = std::collections::HashSet::new();
39 let mut matches: Vec<&'static Recipe> = Vec::new();
40 for mat in state.ac.find_iter(&lower) {
41 let idx = state.recipe_indices[mat.pattern().as_usize()];
42 if seen.insert(idx) {
43 matches.push(&ALL_RECIPES[idx].recipe);
44 }
45 }
46 matches
47}
48
49pub fn all_recipes() -> impl Iterator<Item = &'static Recipe> {
50 ALL_RECIPES.iter().map(|e| &e.recipe)
51}
52
53fn collect_unique_recipes(outputs: &[(&str, &str)]) -> Vec<&'static Recipe> {
54 let mut all_recipes: Vec<&'static Recipe> = Vec::new();
55 let mut seen_titles = std::collections::HashSet::new();
56 for (_label, output) in outputs {
57 for recipe in match_recipes(output) {
58 if seen_titles.insert(recipe.title) {
59 all_recipes.push(recipe);
60 }
61 }
62 }
63 all_recipes
64}
65
66struct RecipeEntry {
67 triggers: &'static [&'static str],
68 recipe: Recipe,
69}
70
71static ALL_RECIPES: &[RecipeEntry] = &[
72 RecipeEntry {
74 triggers: &["very low", "disk:", "free space"],
75 recipe: Recipe {
76 severity: "ACTION",
77 title: "Low disk space",
78 steps: &[
79 "Open Disk Cleanup: press Win+R → type 'cleanmgr' → select C: → check all boxes including 'Windows Update Cleanup'",
80 "Empty the Recycle Bin: right-click desktop icon → Empty Recycle Bin",
81 "Clear Temp folder: press Win+R → type '%temp%' → Ctrl+A → Delete (skip files in use)",
82 "Check largest folders: open PowerShell → Get-ChildItem C:\\ -Recurse -ErrorAction SilentlyContinue | Sort-Object Length -Descending | Select-Object -First 20 FullName, Length",
83 "If space is still tight, run: winget install -e --id Microsoft.PowerToys then use PowerToys Disk Space Analyzer",
84 ],
85 dig_deeper: Some("storage"),
86 },
87 },
88 RecipeEntry {
89 triggers: &["disk_health", "smart", "predictive failure", "wear"],
90 recipe: Recipe {
91 severity: "ACTION",
92 title: "Drive health warning — possible failure",
93 steps: &[
94 "Back up your important files immediately before doing anything else",
95 "Verify the SMART status: open PowerShell (admin) → Get-PhysicalDisk | Select FriendlyName, HealthStatus, OperationalStatus",
96 "If HealthStatus is 'Unhealthy' or 'Warning', replace the drive — do not wait",
97 "For SSDs: check manufacturer's NVMe/SSD tool (Samsung Magician, Crucial Storage Executive, etc.) for wear level",
98 ],
99 dig_deeper: Some("disk_health"),
100 },
101 },
102
103 RecipeEntry {
105 triggers: &["pending reboot", "restart when convenient", "reboot required"],
106 recipe: Recipe {
107 severity: "INVESTIGATE",
108 title: "Restart required",
109 steps: &[
110 "Save your work and restart the computer — pending file operations and updates cannot apply until you do",
111 "After restarting, run this report again to confirm the reboot flag cleared",
112 "If the flag persists after a restart, check Windows Update: Settings → Windows Update → View update history → look for stuck installs",
113 ],
114 dig_deeper: Some("pending_reboot"),
115 },
116 },
117
118 RecipeEntry {
120 triggers: &["critical/error event", "error events in windows event log", "critical error"],
121 recipe: Recipe {
122 severity: "INVESTIGATE",
123 title: "Windows event log errors detected",
124 steps: &[
125 "Find the top error sources: PowerShell → Get-WinEvent -FilterHashtable @{LogName='System','Application';Level=1,2} -MaxEvents 100 | Group-Object ProviderName | Sort-Object Count -Descending | Select -First 10",
126 "One crashing service or driver usually causes most of the noise — focus on the source with the highest count",
127 "For 'Service Control Manager' errors: check which service is crashing → Get-WinEvent -FilterHashtable @{LogName='System';ProviderName='Service Control Manager';Level=2} -MaxEvents 10 | Select Message",
128 "For application crashes: check AppEvent for the faulting app name → Get-WinEvent -FilterHashtable @{LogName='Application';Level=2} -MaxEvents 10 | Select TimeCreated,Message",
129 ],
130 dig_deeper: Some("log_check"),
131 },
132 },
133
134 RecipeEntry {
136 triggers: &["critical service", "not running: windefend", "not running: eventlog", "not running: dnscache"],
137 recipe: Recipe {
138 severity: "ACTION",
139 title: "Critical Windows service not running",
140 steps: &[
141 "Open Services: press Win+R → type 'services.msc' → Enter",
142 "Find the stopped service, right-click → Start",
143 "If it fails to start, right-click → Properties → Recovery tab → set 'First failure' to 'Restart the Service'",
144 "For Windows Defender (WinDefend) stopped: open Windows Security → Virus & threat protection → turn on Real-time protection",
145 "If EventLog is stopped, restart is required — this service cannot be started manually once stopped",
146 ],
147 dig_deeper: Some("services"),
148 },
149 },
150
151 RecipeEntry {
153 triggers: &["internet connectivity: unreachable", "could not ping 1.1.1.1"],
154 recipe: Recipe {
155 severity: "ACTION",
156 title: "No internet connectivity",
157 steps: &[
158 "Check physical connection: is the Ethernet cable plugged in, or is Wi-Fi connected?",
159 "Test gateway reachability: PowerShell → Test-Connection (Get-NetRoute -DestinationPrefix '0.0.0.0/0').NextHop -Count 1",
160 "Flush DNS cache: PowerShell (admin) → Clear-DnsClientCache",
161 "Reset TCP/IP stack: PowerShell (admin) → netsh int ip reset; netsh winsock reset → then restart",
162 "If on Wi-Fi: forget the network and reconnect, or try 'netsh wlan disconnect' then 'netsh wlan connect name=\"SSID\"'",
163 ],
164 dig_deeper: Some("connectivity"),
165 },
166 },
167 RecipeEntry {
168 triggers: &["high latency", "ms rtt — high latency"],
169 recipe: Recipe {
170 severity: "MONITOR",
171 title: "High network latency detected",
172 steps: &[
173 "Run a traceroute to find where the delay is: PowerShell → tracert 1.1.1.1",
174 "Check for background bandwidth consumers: Task Manager → Performance → Open Resource Monitor → Network tab",
175 "If on Wi-Fi, check signal strength and try moving closer to the router or switching to 5GHz",
176 "Check your ISP's status page for outages in your area",
177 ],
178 dig_deeper: Some("latency"),
179 },
180 },
181
182 RecipeEntry {
184 triggers: &["ram:", "very low", "running a bit low", "free of"],
185 recipe: Recipe {
186 severity: "MONITOR",
187 title: "High memory usage",
188 steps: &[
189 "Find the top RAM consumers: Task Manager → Memory column (sort descending)",
190 "Close unused browser tabs — each tab can consume 100–500 MB",
191 "Check for memory leaks: if one process is growing over time without release, restart it",
192 "Disable startup programs that aren't needed: Task Manager → Startup tab → disable high-impact items",
193 "If consistently above 85% with normal usage, consider adding RAM",
194 ],
195 dig_deeper: Some("resource_load"),
196 },
197 },
198
199 RecipeEntry {
201 triggers: &["very high", "check cooling", "elevated under load", "°c — very high"],
202 recipe: Recipe {
203 severity: "ACTION",
204 title: "CPU running hot",
205 steps: &[
206 "Shut down and clean dust from fans and heatsink with compressed air — this is the fix 90% of the time",
207 "Check that all fan headers are connected and fans are spinning on boot",
208 "Verify thermal paste on CPU heatsink — if it's more than 4 years old and temperatures are high, repaste",
209 "In BIOS: confirm fan curve is not set to 'Silent' mode — switch to 'Standard' or 'Performance'",
210 "Check for CPU throttling: PowerShell → Get-WmiObject -Class Win32_Processor | Select Name,CurrentClockSpeed,MaxClockSpeed — if Current is much lower than Max under load, it's throttling",
211 ],
212 dig_deeper: Some("thermal"),
213 },
214 },
215
216 RecipeEntry {
218 triggers: &["real-time protection: disabled", "defender.*disabled", "firewall.*off"],
219 recipe: Recipe {
220 severity: "ACTION",
221 title: "Windows security protection disabled",
222 steps: &[
223 "Re-enable Defender real-time protection: Windows Security → Virus & threat protection → turn on Real-time protection",
224 "If Defender shows as disabled by a third-party antivirus, ensure that AV is up to date and its own real-time protection is on",
225 "Re-enable Windows Firewall: Control Panel → Windows Defender Firewall → Turn Windows Defender Firewall on or off → turn on for all profiles",
226 "Run a quick scan: Windows Security → Virus & threat protection → Quick scan",
227 ],
228 dig_deeper: Some("security"),
229 },
230 },
231 RecipeEntry {
232 triggers: &["threat detected", "quarantine", "malware", "virus found"],
233 recipe: Recipe {
234 severity: "ACTION",
235 title: "Threat detected by Windows Defender",
236 steps: &[
237 "Open Windows Security → Virus & threat protection → Protection history → review detected threats",
238 "If action is 'Quarantined', Defender has contained it — review and remove from quarantine",
239 "Run a full offline scan: Windows Security → Virus & threat protection → Scan options → Microsoft Defender Offline scan",
240 "Change passwords for any accounts accessed on this machine after the infection date",
241 "Check browser extensions for anything you didn't install",
242 ],
243 dig_deeper: Some("defender_quarantine"),
244 },
245 },
246
247 RecipeEntry {
249 triggers: &["windows update", "pending update", "update.*required"],
250 recipe: Recipe {
251 severity: "INVESTIGATE",
252 title: "Windows updates pending",
253 steps: &[
254 "Open Settings → Windows Update → Check for updates",
255 "Install all available updates, then restart when prompted",
256 "If updates are stuck: PowerShell (admin) → net stop wuauserv; net stop bits; net start wuauserv; net start bits",
257 "If stuck for more than 24 hours: run the Windows Update Troubleshooter from Settings → System → Troubleshoot → Other troubleshooters",
258 ],
259 dig_deeper: Some("updates"),
260 },
261 },
262
263 RecipeEntry {
265 triggers: &["yellow bang", "pnp error", "configmanager error", "error code 43", "error code 10", "error code 28", "device problem", "driver error"],
266 recipe: Recipe {
267 severity: "ACTION",
268 title: "Hardware device error detected",
269 steps: &[
270 "Open Device Manager: press Win+R → type 'devmgmt.msc' → Enter",
271 "Look for yellow exclamation marks (!) — right-click → Properties → note the error code and device name",
272 "Error Code 43 (USB/GPU): unplug and replug the device, or roll back the driver: right-click → Properties → Driver → Roll Back Driver",
273 "Error Code 10 (failed to start): update the driver — right-click → Update driver → Search automatically",
274 "Error Code 28 (no driver): download the driver from the manufacturer's website (look up the device name + Windows version)",
275 "For recurring errors: run SFC scan → PowerShell (admin) → sfc /scannow",
276 ],
277 dig_deeper: Some("device_health"),
278 },
279 },
280
281 RecipeEntry {
283 triggers: &["file history: disabled", "no backup configured", "no restore points", "last backup: never", "backup: not configured", "file history.*disabled", "no system restore"],
284 recipe: Recipe {
285 severity: "INVESTIGATE",
286 title: "No backup configured",
287 steps: &[
288 "Enable File History: Settings → System → Storage → Advanced storage settings → Backup options → Add a drive",
289 "Enable System Restore: search 'Create a restore point' → select C: → Configure → turn on protection → OK → Create",
290 "For a full image backup: search 'Backup and Restore (Windows 7)' → Create a system image → choose an external drive",
291 "OneDrive Known Folder Backup covers Desktop/Documents/Pictures: Settings → OneDrive → Backup → Manage backup",
292 "Run your first backup immediately — a backup that has never run has zero value",
293 ],
294 dig_deeper: Some("windows_backup"),
295 },
296 },
297
298 RecipeEntry {
300 triggers: &["smb1 is enabled", "smb1: enabled", "smb1 protocol: enabled", "smb version 1", "smbv1 enabled"],
301 recipe: Recipe {
302 severity: "ACTION",
303 title: "SMB1 protocol enabled — security risk",
304 steps: &[
305 "SMB1 is a deprecated protocol exploited by WannaCry and NotPetya ransomware — disable it immediately",
306 "Disable SMB1: PowerShell (admin) → Set-SmbServerConfiguration -EnableSMB1Protocol $false -Force",
307 "Verify it's off: PowerShell → Get-SmbServerConfiguration | Select EnableSMB1Protocol (should show False)",
308 "If a legacy device (old NAS, printer) stops working after disabling, upgrade its firmware or replace it — do not re-enable SMB1",
309 "Restart required to fully remove the SMB1 listener",
310 ],
311 dig_deeper: Some("shares"),
312 },
313 },
314
315 RecipeEntry {
317 triggers: &["protection state: off", "bitlocker: off", "bitlocker.*not protecting", "encryption status: fully decrypted", "bitlocker.*disabled"],
318 recipe: Recipe {
319 severity: "MONITOR",
320 title: "Drive encryption not enabled",
321 steps: &[
322 "BitLocker encrypts your drive so data is unreadable if the laptop is lost or stolen — strongly recommended on portable machines",
323 "Enable BitLocker: search 'Manage BitLocker' → Turn on BitLocker for C: → follow the wizard",
324 "Save the recovery key to your Microsoft account or print it — you will need it if Windows can't auto-unlock at boot",
325 "Encryption runs in the background and takes 1–3 hours for a typical drive — the PC remains usable during this time",
326 "Requires TPM 1.2+ or USB key; check: PowerShell → Get-Tpm | Select TpmPresent,TpmReady",
327 ],
328 dig_deeper: Some("bitlocker"),
329 },
330 },
331
332 RecipeEntry {
334 triggers: &["dns resolution: failed", "dns: failed", "dns fail", "dns resolution failed", "could not resolve"],
335 recipe: Recipe {
336 severity: "ACTION",
337 title: "DNS resolution failing",
338 steps: &[
339 "Flush DNS cache: PowerShell (admin) → Clear-DnsClientCache",
340 "Test DNS directly: PowerShell → Resolve-DnsName google.com -Server 8.8.8.8 — if this works, your DNS server is the problem",
341 "Switch to a reliable DNS server: PowerShell (admin) → Set-DnsClientServerAddress -InterfaceAlias 'Wi-Fi' -ServerAddresses ('8.8.8.8','1.1.1.1')",
342 "Check if the DNS client service is running: Get-Service Dnscache | Select Status",
343 "If on a corporate network or VPN, contact IT — split DNS may require the VPN to be connected for internal names to resolve",
344 ],
345 dig_deeper: Some("dns_servers"),
346 },
347 },
348
349 RecipeEntry {
351 triggers: &["faulting application", "crash count", "crash frequency", "application hang", "faulting module"],
352 recipe: Recipe {
353 severity: "INVESTIGATE",
354 title: "Application crashing repeatedly",
355 steps: &[
356 "Note the faulting application name and module from the report — these are the most important clues",
357 "If the faulting module is ntdll.dll or a system DLL: run SFC to repair Windows files → PowerShell (admin) → sfc /scannow",
358 "If the faulting module is a third-party DLL (e.g. a codec or plugin): uninstall the associated program",
359 "Update or reinstall the crashing application — corrupted installs are a common cause",
360 "Check for conflicting software: antivirus, screen recorders, and overlays (Discord, GeForce Experience) frequently inject into other processes",
361 "If it is a Microsoft Office app: run the Office repair → Control Panel → Programs → right-click Office → Change → Quick Repair",
362 ],
363 dig_deeper: Some("app_crashes"),
364 },
365 },
366
367 RecipeEntry {
369 triggers: &["vcruntime", "msvcr", "0xc000007b", "side-by-side configuration", "missing runtime", "vc++ redistributable"],
370 recipe: Recipe {
371 severity: "ACTION",
372 title: "Visual C++ runtime missing or corrupt",
373 steps: &[
374 "Download and install the latest Visual C++ Redistributable packages (both x64 and x86) from Microsoft: search 'Visual C++ Redistributable downloads'",
375 "Install all available years: 2015–2022 package covers most apps; older apps may need 2013, 2012, or 2010 separately",
376 "If a specific app shows error 0xc000007b: right-click the app → Properties → Compatibility → Run as administrator",
377 "Repair existing runtimes: Control Panel → Programs → find 'Microsoft Visual C++ 20XX' → Repair",
378 "After installing, restart before testing the application again — runtimes must be registered at boot",
379 ],
380 dig_deeper: Some("installed_software"),
381 },
382 },
383
384 RecipeEntry {
386 triggers: &["expiring within 30 days", "expires in", "certificate expir", "cert.*expir"],
387 recipe: Recipe {
388 severity: "INVESTIGATE",
389 title: "Certificate expiring soon",
390 steps: &[
391 "Open Certificate Manager: press Win+R → type 'certmgr.msc' → check Personal → Certificates for the expiring cert",
392 "Note the certificate subject and issuer — determines who you need to contact for renewal",
393 "For personal/S-MIME certificates: renew through your CA or email provider portal",
394 "For web/TLS certificates on a server: generate a new CSR and submit to your CA before expiry",
395 "For code-signing certificates: do not let these lapse — signed binaries will show 'unknown publisher' warnings after expiry",
396 ],
397 dig_deeper: Some("certificates"),
398 },
399 },
400
401 RecipeEntry {
403 triggers: &["signal: poor", "weak signal", "rssi: -8", "rssi: -9", "signal strength: poor", "quality: poor", "poor signal"],
404 recipe: Recipe {
405 severity: "MONITOR",
406 title: "Wi-Fi signal weak",
407 steps: &[
408 "Move closer to the router or access point — Wi-Fi degrades quickly through walls and floors",
409 "Switch to 5 GHz band if available — faster and less congested in most home environments (but shorter range than 2.4 GHz)",
410 "Check for interference: microwave ovens, baby monitors, and neighboring networks on the same channel all degrade signal",
411 "Change the router's Wi-Fi channel: log into router admin → Wireless settings → try channels 1, 6, or 11 (2.4 GHz) or auto (5 GHz)",
412 "Update the Wi-Fi adapter driver: Device Manager → Network Adapters → right-click adapter → Update driver",
413 "If signal is consistently poor from a fixed desk, consider a powerline adapter or mesh Wi-Fi node nearby",
414 ],
415 dig_deeper: Some("wifi"),
416 },
417 },
418
419 RecipeEntry {
421 triggers: &["time sync failed", "sync failed", "clock drift", "ntp.*error", "w32tm.*fail", "ntp source.*unreachable", "time.*not synchronized"],
422 recipe: Recipe {
423 severity: "INVESTIGATE",
424 title: "System clock not synchronizing",
425 steps: &[
426 "Force a sync now: PowerShell (admin) → w32tm /resync /force",
427 "Check the current NTP source: PowerShell → w32tm /query /source",
428 "If source shows 'Local CMOS Clock' or 'Free-running', the time service has lost its server",
429 "Reset to Microsoft's NTP server: PowerShell (admin) → w32tm /config /manualpeerlist:time.windows.com /syncfromflags:manual /reliable:YES /update",
430 "Restart the time service: PowerShell (admin) → Restart-Service w32tm",
431 "If clock drift is large (>5 minutes), some authentication systems (Kerberos, MFA) will fail until synced",
432 ],
433 dig_deeper: Some("ntp"),
434 },
435 },
436
437 RecipeEntry {
439 triggers: &["no page file", "pagefile: none", "page file: none", "virtual memory: none", "pagefile not configured", "no pagefile"],
440 recipe: Recipe {
441 severity: "INVESTIGATE",
442 title: "Page file not configured",
443 steps: &[
444 "Windows needs a page file even with plenty of RAM — some apps and crash dumps require it",
445 "Re-enable automatic page file management: search 'Adjust the appearance and performance of Windows' → Advanced → Virtual memory → Change → check 'Automatically manage'",
446 "If manually set: assign at least 1.5× your RAM as maximum size on the system drive",
447 "After changing page file settings, restart is required — changes do not take effect until reboot",
448 "Note: if this machine intentionally has no page file (e.g. a RAM disk setup), verify that was deliberate before changing it",
449 ],
450 dig_deeper: Some("pagefile"),
451 },
452 },
453
454 RecipeEntry {
456 triggers: &["corrupt files found", "autorepairrequired: true", "integrity.*failed", "component store corruption", "sfc.*corrupt", "windows resource protection found corrupt"],
457 recipe: Recipe {
458 severity: "ACTION",
459 title: "Windows system file corruption detected",
460 steps: &[
461 "Run SFC to repair corrupt files: PowerShell (admin) → sfc /scannow (takes 5–15 minutes)",
462 "If SFC reports 'Windows Resource Protection found corrupt files but was unable to fix some of them', run DISM next:",
463 "DISM repair: PowerShell (admin) → DISM /Online /Cleanup-Image /RestoreHealth (requires internet access, 10–30 minutes)",
464 "Run SFC again after DISM completes — DISM provides the source files SFC needs",
465 "Restart after both complete, then check Event Viewer for CBS log: Applications and Services Logs → Microsoft → Windows → Servicing",
466 "If corruption persists after both tools: in-place upgrade repair (Windows Setup without wiping data) is the next step",
467 ],
468 dig_deeper: Some("integrity"),
469 },
470 },
471
472 RecipeEntry {
474 triggers: &["stopped unexpectedly", "failed to start", "error 1067", "error 1053", "service terminated", "exited with code", "failed to respond"],
475 recipe: Recipe {
476 severity: "INVESTIGATE",
477 title: "Service failed to start or stopped unexpectedly",
478 steps: &[
479 "Find the failing service name in the report, then check its status: PowerShell → Get-Service <ServiceName>",
480 "Read the specific error from the Application/System event log: Event Viewer → Windows Logs → System → filter for Service Control Manager (Event ID 7034 or 7031)",
481 "Try to start it manually: PowerShell (admin) → Start-Service <ServiceName> — note any error message",
482 "Check if the service account has the right permissions: Services console (services.msc) → right-click → Properties → Log On tab",
483 "Look for a dependent service that failed first — a service won't start if something it requires is stopped",
484 "If the service EXE is missing or corrupt, reinstall the application that owns it",
485 ],
486 dig_deeper: Some("services"),
487 },
488 },
489
490 RecipeEntry {
492 triggers: &["fdenytsconnections: 1", "no enabled rdp firewall", "rdp status: disabled"],
493 recipe: Recipe {
494 severity: "ACTION",
495 title: "Remote Desktop (RDP) is disabled or blocked",
496 steps: &[
497 "Enable RDP: Settings → System → Remote Desktop → Enable Remote Desktop (or PowerShell admin: Set-ItemProperty 'HKLM:\\System\\CurrentControlSet\\Control\\Terminal Server' fDenyTSConnections 0)",
498 "Ensure the RDP firewall rule is enabled: PowerShell (admin) → Enable-NetFirewallRule -DisplayGroup 'Remote Desktop'",
499 "Verify port 3389 is listening after enabling: PowerShell → netstat -an | findstr 3389",
500 "If NLA is required, make sure the connecting user account has the right to log in remotely (must be in Remote Desktop Users group or Administrators)",
501 "Check that Windows Firewall is not blocking the connection — on the host, temporarily allow pings to confirm network path is open",
502 "For cloud VMs: check the security group / NSG allows inbound TCP 3389 from your IP",
503 ],
504 dig_deeper: Some("rdp"),
505 },
506 },
507
508 RecipeEntry {
510 triggers: &["wuauserv: stopped", "wuauserv stopped", "windows update: stopped", "update service stopped", "bits: stopped", "bits stopped"],
511 recipe: Recipe {
512 severity: "ACTION",
513 title: "Windows Update service is stopped or broken",
514 steps: &[
515 "Run the Windows Update Troubleshooter: Settings → Update & Security → Troubleshoot → Additional troubleshooters → Windows Update",
516 "Manually restart the update services: PowerShell (admin) → Stop-Service wuauserv, bits, cryptsvc, msiserver → Start-Service wuauserv, bits, cryptsvc",
517 "Clear the update cache if stuck: PowerShell (admin) → Stop-Service wuauserv → Remove-Item C:\\Windows\\SoftwareDistribution\\* -Recurse -Force → Start-Service wuauserv",
518 "Check for conflicting 3rd-party update tools (WSUS, SCCM, Intune policies) that may be disabling updates",
519 "Run the System Update Readiness Tool: DISM /Online /Cleanup-Image /RestoreHealth",
520 "If the service keeps stopping, check Event Viewer → Windows Logs → System for Windows Update Agent errors around the same time",
521 ],
522 dig_deeper: Some("updates"),
523 },
524 },
525
526 RecipeEntry {
528 triggers: &["classic teams cache:", "new teams cache:", "msteams cache:", "teams cache size"],
529 recipe: Recipe {
530 severity: "INVESTIGATE",
531 title: "Teams cache — clear to resolve most Teams issues",
532 steps: &[
533 "Quit Teams completely: right-click the Teams icon in the system tray → Quit",
534 "Clear Classic Teams cache: open Run (Win+R) → type %AppData%\\Microsoft\\Teams → delete the contents of: Cache, blob_storage, databases, GPUCache, IndexedDB, Local Storage, tmp",
535 "Clear New Teams (MSTeams) cache: open Run → %LocalAppData%\\Packages\\MSTeams_8wekyb3d8bbwe\\LocalCache\\ → delete all contents",
536 "Restart Teams and sign in — cache rebuilds from the server automatically",
537 "If Teams still fails to sign in after clearing cache, also clear credentials: Credential Manager (Win+R → credmgr.msc) → Windows Credentials → remove all MicrosoftOffice16_Data:SSPI:* entries",
538 ],
539 dig_deeper: Some("teams"),
540 },
541 },
542
543 RecipeEntry {
545 triggers: &["token broker: not running", "aad broker plugin: not found", "web account manager: not running", "wam: not running", "aad broker: not found"],
546 recipe: Recipe {
547 severity: "ACTION",
548 title: "Microsoft 365 authentication broker not running",
549 steps: &[
550 "The Windows Account Manager (WAM) and AAD Broker are required for M365 sign-in — if they're not running, Teams, Outlook, and OneDrive will loop on sign-in",
551 "Re-register the token broker: PowerShell (admin) → sfc /scannow — this repairs the system files WAM depends on",
552 "Restart the TokenBroker service: PowerShell (admin) → Restart-Service TokenBroker -ErrorAction SilentlyContinue",
553 "If re-registering doesn't help, sign out of all work accounts: Settings → Accounts → Access work or school → disconnect and reconnect your org account",
554 "On Intune/AAD-joined machines: run 'dsregcmd /leave' then 'dsregcmd /join' (admin) to re-register the device — requires network connectivity to Azure AD",
555 "Check for conflicting credential entries: Credential Manager → Windows Credentials → remove stale MicrosoftOffice16_Data:SSPI:* and MicrosoftOffice15_Data:* entries",
556 ],
557 dig_deeper: Some("identity_auth"),
558 },
559 },
560
561 RecipeEntry {
563 triggers: &["wmi repository is inconsistent", "repository is inconsistent", "wmi: inconsistent", "verifyrepository: inconsistent", "wmi corruption"],
564 recipe: Recipe {
565 severity: "ACTION",
566 title: "WMI repository corrupt — cascading tool failures",
567 steps: &[
568 "WMI corruption breaks PowerShell Get-WmiObject, Defender, Windows Update, and many admin tools — fix it first before investigating other issues",
569 "Stop WMI: PowerShell (admin) → net stop winmgmt /y",
570 "Rebuild the repository: PowerShell (admin) → winmgmt /resetrepository",
571 "Start WMI: PowerShell (admin) → net start winmgmt",
572 "Verify the fix: PowerShell → winmgmt /verifyrepository — should say 'WMI repository is consistent'",
573 "If resetrepository fails, try salvage mode: winmgmt /salvagerepository — this preserves customizations",
574 "Restart the machine after repair — WMI caches are session-scoped and some tools won't see the fix until reboot",
575 ],
576 dig_deeper: Some("wmi_health"),
577 },
578 },
579
580 RecipeEntry {
582 triggers: &["license status: unlicensed", "license status: notification", "activation: not activated", "not genuine", "windows is not activated"],
583 recipe: Recipe {
584 severity: "INVESTIGATE",
585 title: "Windows not activated",
586 steps: &[
587 "Check activation status: Settings → System → Activation — note the exact status message",
588 "If you have a product key: Settings → System → Activation → Change product key → enter the 25-character key",
589 "If the key was tied to a Microsoft account: sign in with that Microsoft account and activation should happen automatically over the internet",
590 "Force activation attempt: PowerShell (admin) → slmgr /ato",
591 "If you get error 0xC004F074 (Key Management Service unreachable): you're on a domain with KMS — contact your IT department, the KMS server may be offline",
592 "If you recently changed hardware (motherboard): activation may need to be relinked — use the Activation Troubleshooter in Settings",
593 ],
594 dig_deeper: Some("activation"),
595 },
596 },
597
598 RecipeEntry {
600 triggers: &["wsearch: stopped", "search service: stopped", "wsearch service: stopped", "indexer: stopped", "windows search: stopped"],
601 recipe: Recipe {
602 severity: "INVESTIGATE",
603 title: "Windows Search not running — search won't find files",
604 steps: &[
605 "Start the Windows Search service: PowerShell (admin) → Start-Service WSearch",
606 "Set it to start automatically: PowerShell (admin) → Set-Service WSearch -StartupType Automatic",
607 "If the service won't start: check Event Viewer → Windows Logs → Application → filter for 'Search' for the specific error",
608 "Rebuild the search index: Settings → Privacy & Security → Windows Search → Advanced indexing options → Advanced → Rebuild — takes 15–60 minutes",
609 "If rebuilding doesn't help, reset the index database: Stop-Service WSearch → delete C:\\ProgramData\\Microsoft\\Search\\Data\\Applications\\Windows\\Windows.edb → Start-Service WSearch",
610 "Restart File Explorer after: PowerShell → Stop-Process -Name explorer → Start-Process explorer",
611 ],
612 dig_deeper: Some("search_index"),
613 },
614 },
615
616 RecipeEntry {
618 triggers: &["sync status: error", "onedrive: not running", "sync errors detected", "onedrive sync error", "known folder backup: not configured"],
619 recipe: Recipe {
620 severity: "INVESTIGATE",
621 title: "OneDrive not syncing",
622 steps: &[
623 "Check the sync status icon in the system tray — hover over it for the specific error message",
624 "Common fix: right-click the OneDrive tray icon → Pause syncing → Resume syncing — resets stuck sync state",
625 "If that doesn't work: right-click the OneDrive tray icon → Settings → Account → Unlink this PC → relink with the same account",
626 "Check for conflicting files: File Explorer → OneDrive folder → look for files with a red X — rename or delete the local copy and let it sync from the cloud",
627 "If the issue is 'Not enough space in OneDrive': manage storage at onedrive.live.com/manage",
628 "Reset OneDrive if all else fails: Win+R → %localappdata%\\Microsoft\\OneDrive\\onedrive.exe /reset — wait 2 minutes, then reopen OneDrive from Start",
629 ],
630 dig_deeper: Some("onedrive"),
631 },
632 },
633
634 RecipeEntry {
636 triggers: &["status: offline", "pending jobs:", "print spooler: stopped", "spooler: stopped"],
637 recipe: Recipe {
638 severity: "INVESTIGATE",
639 title: "Printer offline or stuck print queue",
640 steps: &[
641 "Check the printer is powered on and connected (USB cable or same Wi-Fi network as the PC)",
642 "Clear the stuck print queue: PowerShell (admin) → Stop-Service Spooler → Remove-Item C:\\Windows\\System32\\spool\\PRINTERS\\* -Force → Start-Service Spooler",
643 "If printer shows Offline: right-click the printer in Settings → Printers & scanners → See what's printing → Printer menu → uncheck 'Use Printer Offline'",
644 "For network printers: verify the printer's IP hasn't changed — print a configuration page from the printer itself to check its current IP",
645 "Re-add the printer if the IP changed: Settings → Bluetooth & devices → Printers & scanners → Add device → Add manually → enter the new IP",
646 "If the Print Spooler service is stopped: PowerShell (admin) → Start-Service Spooler → Set-Service Spooler -StartupType Automatic",
647 ],
648 dig_deeper: Some("printers"),
649 },
650 },
651
652 RecipeEntry {
654 triggers: &["profile count: 0", "no mail profiles", "mail profile: none", "no profiles configured", "outlook profiles: 0"],
655 recipe: Recipe {
656 severity: "ACTION",
657 title: "No Outlook mail profile — Outlook will not open",
658 steps: &[
659 "Outlook requires at least one mail profile to start — create one from the Mail control panel applet, not from within Outlook",
660 "Open Mail applet: Win+R → type 'control mlcfg32.cpl' (or search 'Mail' in Control Panel) → Show Profiles → Add",
661 "Enter a profile name (e.g. 'Outlook') → Add Account → enter your email address and follow the auto-configuration wizard",
662 "For Exchange/Microsoft 365: the wizard needs network access to find the Autodiscover DNS record — ensure VPN is connected if this is a corporate account",
663 "For manual setup: choose 'Manual setup' → Microsoft Exchange or compatible service → enter server and username from your IT department",
664 "After creating the profile: launch Outlook, sign in if prompted — first launch will take 2–10 minutes to download the mailbox",
665 ],
666 dig_deeper: Some("outlook"),
667 },
668 },
669
670 RecipeEntry {
672 triggers: &["rpcauthnlevelprivacyenabled: 0", "printnightmare rpc mitigation not applied", "point and print allows silent", "finding: printnightmare"],
673 recipe: Recipe {
674 severity: "INVESTIGATE",
675 title: "PrintNightmare (CVE-2021-34527) mitigation not applied",
676 steps: &[
677 "Apply the RPC authentication hardening fix: PowerShell (admin) → Set-ItemProperty 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Print' -Name RpcAuthnLevelPrivacyEnabled -Value 1 -Type DWord",
678 "Restrict Point and Print driver installs to administrators: PowerShell (admin) → Set-ItemProperty 'HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows NT\\Printers\\PointAndPrint' -Name RestrictDriverInstallationToAdministrators -Value 1 -Type DWord",
679 "If the Print Spooler is not needed (e.g. server, workstation that never prints remotely): PowerShell (admin) → Stop-Service Spooler → Set-Service Spooler -StartupType Disabled",
680 "Verify patch KB5004945 or later is installed: check Windows Update history for July 2021 security updates",
681 "Restart the Spooler service after registry changes: PowerShell (admin) → Restart-Service Spooler",
682 ],
683 dig_deeper: Some("print_spooler"),
684 },
685 },
686
687 RecipeEntry {
689 triggers: &["winsock catalog corrupted", "winsock reset", "tcp/ip stack", "netsh int ip reset", "no internet after update", "network stack corrupt"],
690 recipe: Recipe {
691 severity: "ACTION",
692 title: "TCP/IP or Winsock stack needs reset",
693 steps: &[
694 "Open PowerShell as administrator",
695 "Reset the TCP/IP stack: netsh int ip reset",
696 "Reset the Winsock catalog: netsh winsock reset",
697 "Restart the computer — these changes require a reboot to take effect",
698 "After restart, verify internet is restored: ping 1.1.1.1",
699 "If still broken, run: ipconfig /release then ipconfig /renew to get a fresh DHCP lease",
700 ],
701 dig_deeper: Some("connectivity"),
702 },
703 },
704
705 RecipeEntry {
707 triggers: &["wlansvc: stopped", "wlan autoconfig: stopped", "wlan autoconfig service: stopped", "wireless autoconfig: stopped"],
708 recipe: Recipe {
709 severity: "ACTION",
710 title: "WLAN AutoConfig service stopped — Wi-Fi unavailable",
711 steps: &[
712 "Open PowerShell as administrator",
713 "Start the WLAN AutoConfig service: Start-Service Wlansvc",
714 "Set it to auto-start: Set-Service Wlansvc -StartupType Automatic",
715 "Verify Wi-Fi adapter is visible: Get-NetAdapter | Where-Object {$_.MediaType -eq '802.11'}",
716 "If no Wi-Fi adapter appears after starting the service, check Device Manager for a disabled wireless adapter",
717 "If the service fails to start, update the Wi-Fi adapter driver via Device Manager → right-click adapter → Update driver",
718 ],
719 dig_deeper: Some("wifi"),
720 },
721 },
722
723 RecipeEntry {
725 triggers: &[
726 "system crashes / unexpected shutdowns:",
727 "bsod (bugcheck)",
728 "unexpected shutdown",
729 "blue screen",
730 "stop code",
731 "critical_process_died",
732 "memory_management",
733 "kernel_security_check_failure",
734 "page_fault_in_nonpaged_area",
735 "irql_not_less_or_equal",
736 "system_thread_exception",
737 "kmode_exception_not_handled",
738 "ntfs_file_system",
739 "bsod after",
740 "keeps crashing",
741 "random restart",
742 "random reboot",
743 ],
744 recipe: Recipe {
745 severity: "ACTION",
746 title: "Blue screen (BSOD) or unexpected shutdown",
747 steps: &[
748 "Find the stop code: Settings → System → About → Blue screen of death stop code, or check Event Viewer (Win+X → Event Viewer → Windows Logs → System → filter for Event ID 41 and 1001)",
749 "Run memory diagnostics: Win+R → type 'mdsched' → restart and test now — leave it running overnight if possible; replace RAM if errors found",
750 "Check for corrupted system files: PowerShell (admin) → sfc /scannow, then DISM /Online /Cleanup-Image /RestoreHealth (takes 15–30 min, requires internet)",
751 "Roll back recently installed drivers: Device Manager → look for recently updated drivers (sort by date) → right-click → Properties → Driver → Roll Back Driver",
752 "Check for Windows Update issues: some BSODs after updates are fixed by the next cumulative update — check Windows Update for pending updates",
753 "For memory-related stop codes (MEMORY_MANAGEMENT, PAGE_FAULT_IN_NONPAGED_AREA): reseat RAM sticks (power off, remove and firmly reinsert each stick)",
754 "Read the minidump for the exact faulting module: PowerShell (admin) → Get-ChildItem C:\\Windows\\Minidump | Sort-Object LastWriteTime -Descending | Select-Object -First 3 FullName — open with WinDbg or upload to https://www.osronline.com/page.cfm?name=analyze",
755 "If BSODs persist: run hematite --inspect disk_health,thermal to rule out failing storage or overheating as the root cause",
756 ],
757 dig_deeper: Some("recent_crashes"),
758 },
759 },
760
761 RecipeEntry {
763 triggers: &[
764 "global: deny",
765 "camera access is globally denied",
766 "no camera devices found via pnp",
767 "camera not working",
768 "webcam not working",
769 "camera not detected",
770 "camera blocked",
771 "camera privacy",
772 "no cameras found",
773 ],
774 recipe: Recipe {
775 severity: "ACTION",
776 title: "Camera / webcam not working or blocked",
777 steps: &[
778 "Check Windows camera privacy first: Settings → Privacy & security → Camera → toggle 'Let apps access your camera' ON",
779 "If the global toggle is already on, check the specific app (Teams, Zoom, etc.) — scroll down on the same page and enable it for the app individually",
780 "Test the camera works at all: Win+R → type 'camera' → open the Camera app — if it works there, the issue is app-specific permissions, not the device",
781 "If Camera app also fails: open Device Manager (Win+X) → Cameras — look for a yellow bang (error) on the device, right-click → Update driver → Search automatically",
782 "If no camera appears in Device Manager at all: check if the camera is physically disabled via a keyboard shortcut (often Fn+F key with a camera icon), or disabled in BIOS/UEFI",
783 "Reinstall the camera driver: Device Manager → Cameras → right-click → Uninstall device (check 'Delete driver' box) → restart PC; Windows re-installs the driver on boot",
784 "For external USB cameras: try a different USB port or USB cable; test on another machine to confirm the hardware is not faulty",
785 "In Teams or Zoom: check in-app settings → Video/Camera device selector — make sure the correct camera is selected (especially if multiple cameras exist)",
786 ],
787 dig_deeper: Some("camera"),
788 },
789 },
790
791 RecipeEntry {
793 triggers: &["firewall service: stopped", "mpssvc: stopped", "windows firewall service: stopped", "firewall: stopped"],
794 recipe: Recipe {
795 severity: "ACTION",
796 title: "Windows Firewall service stopped — security risk",
797 steps: &[
798 "Open PowerShell as administrator",
799 "Start the Windows Firewall service: Start-Service MpsSvc",
800 "Set it to auto-start: Set-Service MpsSvc -StartupType Automatic",
801 "Verify all profiles are active: Get-NetFirewallProfile | Select Name, Enabled",
802 "If MpsSvc fails to start, check for third-party firewall software that may have disabled it",
803 "In an enterprise environment, the firewall may be managed by Group Policy — run gpresult /r to check",
804 ],
805 dig_deeper: Some("security"),
806 },
807 },
808
809 RecipeEntry {
811 triggers: &["core audio services are not running", "no audio endpoints", "audio service not running", "audiosrv: not running", "no playback devices", "no sound device"],
812 recipe: Recipe {
813 severity: "ACTION",
814 title: "No audio — Windows Audio service or device issue",
815 steps: &[
816 "Restart the Windows Audio service: PowerShell (admin) → Restart-Service Audiosrv -Force",
817 "If the service restarts but no sound, check Device Manager for audio device errors: Win+X → Device Manager → Sound, video and game controllers",
818 "Right-click any device with a yellow bang → Update driver → Search automatically",
819 "Check the audio device is not muted or disabled: right-click volume icon in taskbar → Open Sound settings → check Output device",
820 "For Bluetooth headsets: run hematite --inspect bluetooth to check the AVCTP service and audio crossover state",
821 "If using a USB audio device: unplug and replug the device, or try a different USB port",
822 "Last resort — reinstall the audio driver: Device Manager → Sound → right-click device → Uninstall device → Restart PC (Windows re-installs the driver)",
823 ],
824 dig_deeper: Some("audio"),
825 },
826 },
827
828 RecipeEntry {
830 triggers: &["bluetooth-related services are not fully running", "no bluetooth radio", "bluetooth device issues", "bluetooth adapter not detected", "bthserv: stopped", "bluetooth service not running"],
831 recipe: Recipe {
832 severity: "ACTION",
833 title: "Bluetooth not working — service or hardware issue",
834 steps: &[
835 "Restart the Bluetooth services: PowerShell (admin) → Restart-Service bthserv -Force",
836 "If the service starts but devices won't pair: toggle Bluetooth off then on in Settings → Bluetooth & devices",
837 "Remove the device and re-pair it: Settings → Bluetooth & devices → find the device → Remove → Add device",
838 "If no Bluetooth adapter is detected: check Device Manager → Bluetooth — look for missing or disabled adapters",
839 "For a disabled adapter: right-click → Enable device; for a missing adapter, check if Bluetooth is disabled in BIOS/UEFI or via a physical switch/key combination",
840 "Update the Bluetooth driver: Device Manager → Bluetooth → right-click adapter → Update driver",
841 "For Bluetooth audio: verify the device is set as the default audio output in Settings → System → Sound",
842 ],
843 dig_deeper: Some("bluetooth"),
844 },
845 },
846
847 RecipeEntry {
849 triggers: &["msiserver) is disabled", "msiexec.exe is missing", "installer transaction already in progress", "recent installer failures were recorded", "microsoft desktop app installer is missing", "msiserver: disabled"],
850 recipe: Recipe {
851 severity: "ACTION",
852 title: "App installation failing — Windows Installer issue",
853 steps: &[
854 "Re-enable and start the Windows Installer service: PowerShell (admin) → Set-Service msiserver -StartupType Manual; Start-Service msiserver",
855 "If an installer transaction is stuck, clear it: PowerShell (admin) → msiexec /unreg; msiexec /regserver",
856 "If a pending reboot is blocking installs: save your work and restart the computer first",
857 "For winget install failures: ensure Microsoft Desktop App Installer is current — open Microsoft Store → search 'App Installer' → Update",
858 "Clear the Windows Installer temp files: delete C:\\Windows\\Installer\\*.tmp",
859 "If MSI installs still fail after the above, run: sfc /scannow in an admin PowerShell to repair system files that MSI depends on",
860 ],
861 dig_deeper: Some("installer_health"),
862 },
863 },
864
865 RecipeEntry {
867 triggers: &[
868 "vpn adapter detected",
869 "no vpn adapters found",
870 "vpn client service",
871 "vpn tunnel",
872 "vpn not connecting",
873 "vpn disconnecting",
874 "split tunnel",
875 "ras/vpn",
876 "rasman",
877 ],
878 recipe: Recipe {
879 severity: "INVESTIGATE",
880 title: "VPN not connecting or disconnecting",
881 steps: &[
882 "Restart the Remote Access Connection Manager service: PowerShell (admin) → Restart-Service RasMan -Force",
883 "Check for a proxy conflict: Settings → Network & Internet → Proxy — disable 'Automatically detect settings' temporarily and test again",
884 "Flush DNS and reset Winsock (VPN can leave stale routes): PowerShell (admin) → ipconfig /flushdns; netsh winsock reset",
885 "If using a corporate VPN client (Cisco AnyConnect, GlobalProtect, Pulse): reinstall the client or run the client's repair option from Add/Remove Programs",
886 "Check Windows Firewall isn't blocking the VPN ports: run hematite --inspect firewall_rules and look for rules blocking UDP 500, UDP 4500, or TCP 1723",
887 "If the VPN adapter shows but won't authenticate: run hematite --inspect identity_auth to check if the AAD/WAM token broker is healthy",
888 "For WireGuard or OpenVPN: verify the tunnel config file is intact and the remote server is reachable: ping <vpn-server-ip>",
889 ],
890 dig_deeper: Some("vpn"),
891 },
892 },
893
894 RecipeEntry {
896 triggers: &[
897 "display driver",
898 "refresh rate:",
899 "bits per pixel:",
900 "monitor:",
901 "screen flickering",
902 "display flickering",
903 "screen flashing",
904 "black screen",
905 "resolution wrong",
906 "wrong resolution",
907 ],
908 recipe: Recipe {
909 severity: "INVESTIGATE",
910 title: "Screen flickering or display issues",
911 steps: &[
912 "Update or roll back the display driver: Device Manager → Display Adapters → right-click GPU → Update driver (or Roll Back Driver if flickering started after a recent update)",
913 "Check for a refresh rate mismatch: Settings → System → Display → Advanced display → verify the refresh rate matches what your monitor supports",
914 "Inspect the cable: reseat or replace the HDMI/DisplayPort cable — a loose or failing cable is the most common cause of flickering",
915 "Check if Task Manager flickers when you open it (Win+X → Task Manager): if Task Manager does NOT flicker, the cause is a software/app conflict, not the driver",
916 "Disable hardware acceleration in Chrome/Edge: Settings → System → turn off 'Use hardware acceleration when available', then restart the browser",
917 "Run hematite --inspect device_health to check for GPU or display adapter PnP errors (yellow bangs in Device Manager)",
918 "If using NVIDIA: open NVIDIA Control Panel → Manage 3D Settings → verify G-Sync/VRR is correctly enabled or disabled for your panel type",
919 "For laptops: test on an external monitor — if the external is stable, the laptop panel or cable is the likely failure point",
920 ],
921 dig_deeper: Some("display_config"),
922 },
923 },
924
925 RecipeEntry {
927 triggers: &[
928 "no recording endpoints found",
929 "recording endpoint",
930 "microphone privacy",
931 "microphone access: denied",
932 "input device",
933 "microphone not working",
934 "mic not working",
935 "mic not detected",
936 "microphone blocked",
937 ],
938 recipe: Recipe {
939 severity: "ACTION",
940 title: "Microphone not working or not detected",
941 steps: &[
942 "Check the privacy setting: Settings → Privacy & security → Microphone → ensure 'Microphone access' is On and your app has permission",
943 "Set the correct default input device: right-click the speaker icon in the taskbar → Sound settings → Input → choose the correct microphone",
944 "Restart the Windows Audio service: PowerShell (admin) → Restart-Service Audiosrv -Force; Restart-Service AudioEndpointBuilder -Force",
945 "Check the microphone is not muted at the hardware level — look for a physical mute button on the mic, headset, or laptop keyboard (Fn+F-key)",
946 "Run hematite --inspect audio to see which recording endpoints Windows has found and their current state",
947 "Update the audio driver: Device Manager → Sound, video and game controllers → right-click the audio device → Update driver",
948 "For a USB microphone: unplug, wait 10 seconds, replug — Windows re-enumerates the device and may fix a bad enumeration state",
949 "If the microphone works in one app but not another (e.g. works in Voice Recorder but not Teams): check the app's own audio settings, not Windows settings",
950 ],
951 dig_deeper: Some("audio"),
952 },
953 },
954
955 RecipeEntry {
957 triggers: &[
958 "wbiosrvc",
959 "biometric service",
960 "windows hello",
961 "pin not working",
962 "fingerprint not working",
963 "logon failure",
964 "event id 4625",
965 "failed logon",
966 "credential provider",
967 "sign-in failed",
968 "can't sign in",
969 ],
970 recipe: Recipe {
971 severity: "ACTION",
972 title: "Login, PIN, or Windows Hello not working",
973 steps: &[
974 "Reset the PIN: on the sign-in screen, click 'I forgot my PIN' — Windows will verify your Microsoft account or Azure AD identity and let you set a new PIN without needing the old one",
975 "Restart the Windows Biometric Service: PowerShell (admin) → Restart-Service WbioSrvc -Force",
976 "If fingerprint or face recognition stopped working: Settings → Accounts → Sign-in options → remove and re-enroll the biometric credential",
977 "For 'something went wrong' on the PIN screen: Settings → Accounts → Sign-in options → PIN (Windows Hello) → I forgot my PIN",
978 "Check for account lockout (repeated failed logins): run hematite --inspect sign_in and look for Event ID 4625 (failed logon) frequency",
979 "If the machine is domain-joined and the domain controller is unreachable, Windows may not accept domain credentials — use a local admin account as a fallback",
980 "If all sign-in methods fail at the lock screen, boot to Windows Recovery (hold Shift while clicking Restart) → Troubleshoot → Reset this PC as a last resort",
981 ],
982 dig_deeper: Some("sign_in"),
983 },
984 },
985
986 RecipeEntry {
988 triggers: &[
989 "disk queue length:",
990 "average disk queue",
991 "disk i/o",
992 "high disk usage",
993 "disk at 100",
994 "100% disk",
995 "disk thrashing",
996 "disk saturation",
997 ],
998 recipe: Recipe {
999 severity: "INVESTIGATE",
1000 title: "Disk at 100% — high disk I/O",
1001 steps: &[
1002 "Identify the process driving disk I/O: run hematite --inspect processes and look at the R/W column for the top consumer",
1003 "Common culprits: Windows Search indexer (SearchIndexer.exe), Windows Update (TiWorker.exe, WUDFHost.exe), Antivirus scan, or a runaway backup job",
1004 "If Windows Search is the cause: Settings → Search → Windows Search → Indexing Options → Pause indexing for 15 minutes and see if disk drops",
1005 "If Windows Update (TiWorker.exe): let it finish — fighting a mid-update installation makes things worse; check Windows Update status in Settings",
1006 "Check for a failing drive: run hematite --inspect disk_health — a drive with SMART errors can cause 100% disk usage as the OS retries failing sectors",
1007 "Disable Windows Superfetch/SysMain if you have an SSD: PowerShell (admin) → Stop-Service SysMain; Set-Service SysMain -StartupType Disabled",
1008 "Check the page file: if RAM is full, Windows pages to disk constantly — run hematite --inspect pagefile and resource_load to verify",
1009 "For persistent 100% disk on an HDD: consider upgrading to an SSD — HDDs cannot sustain the I/O demand of modern Windows workloads",
1010 ],
1011 dig_deeper: Some("processes"),
1012 },
1013 },
1014
1015 RecipeEntry {
1017 triggers: &[
1018 "[err:",
1019 "usb device not recognized",
1020 "unknown usb device",
1021 "device descriptor request failed",
1022 "usb not working",
1023 "usb port not working",
1024 ],
1025 recipe: Recipe {
1026 severity: "ACTION",
1027 title: "USB device not recognized or not working",
1028 steps: &[
1029 "Unplug the USB device, wait 10 seconds, then replug it — Windows re-enumerates the USB controller and often clears a bad enumeration state",
1030 "Try a different USB port — especially try a USB 2.0 port if the device was on a USB 3.0 port (some older accessories have compatibility issues with 3.x)",
1031 "Restart the USB Host Controller: Device Manager → Universal Serial Bus controllers → right-click each 'USB Root Hub' → Disable device, then Enable device",
1032 "Run the USB troubleshooter: Settings → System → Troubleshoot → Other troubleshooters → USB",
1033 "Check for driver errors: run hematite --inspect device_health to see PnP error codes — Error Code 43 is an unrecoverable device error requiring a driver reinstall or device replacement",
1034 "Update chipset and USB controller drivers: go to your motherboard manufacturer's website (ASUS, MSI, Gigabyte, ASRock) and download the latest chipset driver for your platform",
1035 "If the device worked before: uninstall the device in Device Manager (right-click → Uninstall device, check 'Delete the driver software'), then replug so Windows installs a fresh driver",
1036 "For persistent issues on all ports: run hematite --inspect device_health and check if 'USB Root Hub' itself shows an error — this points to a chipset/driver issue, not the accessory",
1037 ],
1038 dig_deeper: Some("device_health"),
1039 },
1040 },
1041
1042 RecipeEntry {
1044 triggers: &[
1045 "there is no wireless interface",
1046 "no wireless interface detected",
1047 "no wi-fi devices found",
1048 "wi-fi adapter disconnected",
1049 "no wireless tool available",
1050 "no wireless networks",
1051 "wifi adapter off",
1052 "wireless adapter disabled",
1053 "airplane mode",
1054 ],
1055 recipe: Recipe {
1056 severity: "ACTION",
1057 title: "No Wi-Fi networks visible — adapter or driver issue",
1058 steps: &[
1059 "Make sure the Wi-Fi adapter is on: Action Center (bottom-right) → click the Wi-Fi tile to toggle it on; also check the physical Wi-Fi key (Fn+F-key) on laptops",
1060 "Check Airplane Mode is off: Settings → Network & Internet → Airplane mode → Off",
1061 "Restart WLAN AutoConfig service: PowerShell (admin) → Restart-Service Wlansvc -Force",
1062 "Toggle the adapter off and on: Device Manager → Network Adapters → right-click the Wi-Fi adapter → Disable device, wait 5 seconds, Enable device",
1063 "Update the Wi-Fi driver: Device Manager → Network Adapters → right-click the Wi-Fi adapter → Update driver → Search automatically",
1064 "If no Wi-Fi adapter appears in Device Manager: run hematite --inspect device_health and look for hidden or missing network devices; the adapter may need a driver install from the laptop/motherboard manufacturer",
1065 "For Intel Wi-Fi adapters: download the latest driver from Intel's website (search 'Intel Wi-Fi driver') — the Windows generic driver sometimes loses network scan capability after Windows updates",
1066 "Reset network settings as a last resort: PowerShell (admin) → netsh wlan delete profile name=* then restart; this removes all saved Wi-Fi profiles but often fixes a corrupt wireless profile store",
1067 ],
1068 dig_deeper: Some("wifi"),
1069 },
1070 },
1071
1072 RecipeEntry {
1074 triggers: &[
1075 "server unreachable (ping failed)",
1076 "reachable:false",
1077 "share not accessible",
1078 "network path not found",
1079 "access is denied",
1080 "share access failed",
1081 "smb share unreachable",
1082 "network share",
1083 ],
1084 recipe: Recipe {
1085 severity: "INVESTIGATE",
1086 title: "Network share or mapped drive not accessible",
1087 steps: &[
1088 "Verify basic connectivity to the server: PowerShell → Test-NetConnection -ComputerName <server> -Port 445 (SMB port) — if this fails, the issue is network-level, not share-level",
1089 "Check the server is online: ping <server-name-or-IP> from PowerShell",
1090 "Confirm the share name is correct: Net View \\\\<server> lists all shares exposed by the server",
1091 "Re-enter credentials: Windows Credential Manager may have stale credentials — Win+R → control keymgr.dll → remove entries for the target server, then retry the share",
1092 "If 'Access Denied': verify your account has been granted share and NTFS permissions on the server side — contact the server admin to confirm your permissions",
1093 "Check SMB1 is not required: some old NAS devices only speak SMB1. Run hematite --inspect shares to see if SMB1 is disabled locally — if so, either enable it (security risk) or update the NAS firmware",
1094 "For domain environments: if the server name resolves but SMB fails, check if Kerberos is working — run hematite --inspect domain_health to verify DC reachability and GPO refresh",
1095 "Map the drive manually to force a fresh credential prompt: File Explorer → This PC → Map network drive → \\\\<server>\\<share> → check 'Connect using different credentials'",
1096 ],
1097 dig_deeper: Some("share_access"),
1098 },
1099 },
1100
1101 RecipeEntry {
1103 triggers: &[
1104 "microsoft.windowsstore | status: missing",
1105 "appx |",
1106 "desktopappinstaller | status: missing",
1107 "store is not responding",
1108 "wsreset",
1109 "appx package",
1110 "microsoft store not opening",
1111 "microsoft store not working",
1112 "store app not installing",
1113 ],
1114 recipe: Recipe {
1115 severity: "ACTION",
1116 title: "Microsoft Store or AppX apps not working",
1117 steps: &[
1118 "Reset the Store cache: open Run (Win+R) → type wsreset.exe → Enter. A blank window opens, waits ~30 seconds, then the Store launches automatically. This clears the Store cache without removing app data.",
1119 "If the Store still won't open: PowerShell (admin) → Get-AppXPackage -AllUsers Microsoft.WindowsStore | Foreach {Add-AppxPackage -DisableDevelopmentMode -Register \"$($_.InstallLocation)\\AppXManifest.xml\"} to re-register the Store package",
1120 "Ensure the Windows Update service is running: PowerShell (admin) → Start-Service wuauserv — the Store update pipeline depends on Windows Update",
1121 "Check AppX installer services: run hematite --inspect installer_health to see if AppX or Store services are in a failed state",
1122 "For 'This app can't open' errors: Settings → Apps → Apps & features → find the app → Advanced options → Reset — this wipes the app's local data but usually fixes launch failures",
1123 "If apps fail to install from the Store with error code 0x80073D02 or 0x80073CF9: run: PowerShell (admin) → Get-AppXPackage -AllUsers | Foreach {Add-AppxPackage -DisableDevelopmentMode -Register \"$($_.InstallLocation)\\AppXManifest.xml\"} to rebuild the full AppX registration",
1124 "For persistent Store issues: Settings → System → Troubleshoot → Other troubleshooters → Windows Store Apps",
1125 ],
1126 dig_deeper: Some("installer_health"),
1127 },
1128 },
1129
1130 RecipeEntry {
1132 triggers: &[
1133 "kernel-power",
1134 "power-troubleshooter",
1135 "sleep issue",
1136 "hibernate fail",
1137 "won't wake",
1138 "stuck after sleep",
1139 "wake after sleep",
1140 "sleep fail",
1141 "hibernate issue",
1142 "fast startup",
1143 "s0 low power idle",
1144 "system restart is pending",
1145 "pending file rename operations",
1146 ],
1147 recipe: Recipe {
1148 severity: "INVESTIGATE",
1149 title: "PC won't sleep, hibernate, or wake properly",
1150 steps: &[
1151 "Check what's preventing sleep: open PowerShell (admin) → powercfg /requests — shows apps or services actively blocking sleep",
1152 "See what woke the PC last time: PowerShell (admin) → powercfg /lastwake — identifies the wake source (scheduled task, device, network adapter)",
1153 "Check for wake timers: PowerShell (admin) → powercfg /waketimers — lists all wake timers; if unexpected, disable individual timers in Task Scheduler",
1154 "Disable Fast Startup (common cause of wake/sleep issues): Settings → System → Power & sleep → Additional power settings → Choose what the power buttons do → uncheck 'Turn on fast startup'",
1155 "Disable wake-on-LAN if not needed: Device Manager → Network Adapters → right-click NIC → Properties → Power Management → uncheck 'Allow this device to wake the computer'",
1156 "If the PC wakes immediately after sleeping: a device (USB hub, mouse, keyboard) is triggering wakeup — run PowerShell (admin) → powercfg /devicequery wake_armed to see which device is responsible, then disable its wake permission in Device Manager → Properties → Power Management",
1157 "For hibernate-specific issues: PowerShell (admin) → powercfg /h on to ensure hibernation is enabled; or /h off to disable it if you don't use hibernate",
1158 "Run the Power troubleshooter: Settings → System → Troubleshoot → Other troubleshooters → Power",
1159 ],
1160 dig_deeper: Some("log_check"),
1161 },
1162 },
1163
1164 RecipeEntry {
1166 triggers: &[
1167 "hid keyboard",
1168 "hid mouse",
1169 "hid-compliant",
1170 "no hid devices",
1171 "input device",
1172 "keyboard not detected",
1173 "mouse not detected",
1174 "touchpad not working",
1175 "trackpad not working",
1176 "keyboard frozen",
1177 "mouse frozen",
1178 ],
1179 recipe: Recipe {
1180 severity: "ACTION",
1181 title: "Keyboard, mouse, or touchpad not working",
1182 steps: &[
1183 "For USB keyboards/mice: unplug, wait 10 seconds, replug into a different USB port — try a USB 2.0 port (blue or black) if it was in a USB 3.0 port (blue-interior)",
1184 "For wireless keyboards/mice: replace the battery and re-pair the USB receiver (unplug receiver, replug, hold the pairing button on the device)",
1185 "Restart the HID (Human Interface Device) service: PowerShell (admin) → Restart-Service hidserv -Force",
1186 "Check for driver errors: run hematite --inspect device_health — look for keyboard or mouse devices showing error codes in Device Manager",
1187 "Roll back or update the keyboard/mouse driver: Device Manager → Keyboards or Mice and other pointing devices → right-click → Update driver or Roll Back Driver",
1188 "For laptop touchpad: check if a keyboard shortcut disabled it (usually Fn+F7 or a dedicated touchpad key) — press it to toggle",
1189 "If touchpad disappears after Windows Update: check the laptop manufacturer's website (Dell, HP, Lenovo, ASUS) for a touchpad driver update — generic Windows HID drivers often lose touchpad gestures",
1190 "Run the Hardware troubleshooter: PowerShell (admin) → msdt.exe -id DeviceDiagnostic",
1191 ],
1192 dig_deeper: Some("peripherals"),
1193 },
1194 },
1195
1196 RecipeEntry {
1198 triggers: &[
1199 "bytes sent (mb):",
1200 "bytes received (mb):",
1201 "rx errors:",
1202 "tx errors:",
1203 "high bandwidth",
1204 "bandwidth usage",
1205 "network saturation",
1206 "network usage high",
1207 "upload high",
1208 "download high",
1209 ],
1210 recipe: Recipe {
1211 severity: "INVESTIGATE",
1212 title: "High network usage — something is using all the bandwidth",
1213 steps: &[
1214 "Identify the process: run hematite --inspect processes to see CPU/RAM, then hematite --inspect connections to see which process has the most active TCP connections",
1215 "Check for Windows Update downloading in the background: Settings → Windows Update — if an update is downloading, let it finish or schedule it for off-hours",
1216 "Check for OneDrive or backup software syncing: OneDrive icon in taskbar → pause sync temporarily to test; same for Dropbox, Google Drive, Backup",
1217 "Check for delivery optimization (Windows Update peer sharing): Settings → Windows Update → Advanced options → Delivery Optimization → turn off 'Allow downloads from other PCs'",
1218 "Look for malware/miners: high sustained upload to unknown IPs is a red flag — run hematite --inspect security to check Defender status, then run a full Defender scan",
1219 "Use Resource Monitor for real-time drill-down: Task Manager → Performance tab → Open Resource Monitor → Network tab → shows per-process bytes/sec in real time",
1220 "For gaming: check for background game patching (Steam, Epic, Xbox) — pause downloads in each game client's settings",
1221 "If a browser is the top consumer: extensions can cause heavy network usage — try a private/incognito window to isolate, then disable extensions one at a time",
1222 ],
1223 dig_deeper: Some("network_stats"),
1224 },
1225 },
1226
1227 RecipeEntry {
1229 triggers: &[
1230 "crackling",
1231 "audio distortion",
1232 "audio stuttering",
1233 "audio popping",
1234 "audio drops out",
1235 "audio cutting",
1236 "audio lag",
1237 "sound crackling",
1238 "sound distortion",
1239 "sound stuttering",
1240 "audio glitch",
1241 "dpc latency",
1242 "exclusive mode",
1243 ],
1244 recipe: Recipe {
1245 severity: "INVESTIGATE",
1246 title: "Audio crackling, distortion, or stuttering",
1247 steps: &[
1248 "Check the sample rate and bit depth: right-click the speaker icon → Sound settings → More sound settings → Playback tab → right-click your speaker → Properties → Advanced → set to '24 bit, 48000 Hz (Studio Quality)' or match your headset's spec",
1249 "Disable audio enhancements: in the same Advanced tab → uncheck 'Enable audio enhancements' — Realtek/DTS/Nahimic enhancements are a common cause of crackling",
1250 "Update or reinstall the audio driver: Device Manager → Sound, video and game controllers → right-click your audio device → Update driver; or download the latest from your motherboard/laptop manufacturer (Realtek, IDT, Intel SST)",
1251 "Check DPC (Deferred Procedure Call) latency: download LatencyMon (free, latencymon.com) and run it while crackling occurs — identifies which driver or service is causing audio buffer underruns",
1252 "Disable exclusive mode: right-click speaker → Properties → Advanced → uncheck 'Allow applications to take exclusive control of this device' — prevents apps like Spotify or Discord from monopolizing the audio device",
1253 "For Bluetooth audio crackling: increase Bluetooth quality by switching codec — in Bluetooth settings, ensure the device is using aptX or AAC instead of SBC; also move the device closer to reduce interference",
1254 "Disable power management on the audio adapter: Device Manager → Sound → right-click audio device → Properties → Power Management → uncheck 'Allow the computer to turn off this device to save power'",
1255 "If crackling started after a Windows Update: Device Manager → right-click audio device → Roll Back Driver to the previous version",
1256 ],
1257 dig_deeper: Some("audio"),
1258 },
1259 },
1260
1261 RecipeEntry {
1263 triggers: &[
1264 "browser crash",
1265 "webview2 runtime: missing",
1266 "webview2: not installed",
1267 "browser slow",
1268 "browser freezing",
1269 "browser not responding",
1270 "browser high cpu",
1271 "chrome slow",
1272 "edge slow",
1273 "firefox slow",
1274 "browser not opening",
1275 "browser crashing",
1276 "browser keeps closing",
1277 ],
1278 recipe: Recipe {
1279 severity: "INVESTIGATE",
1280 title: "Browser slow, crashing, or not opening",
1281 steps: &[
1282 "Clear the browser cache: in Chrome/Edge → Ctrl+Shift+Delete → check 'Cached images and files' → All time → Clear data; this is the single most effective fix for browser slowness",
1283 "Test in a private/incognito window (Ctrl+Shift+N in Chrome/Edge, Ctrl+Shift+P in Firefox) — if the browser is fast in private mode, an extension is the cause",
1284 "Disable extensions one at a time: browser menu → Extensions (or Add-ons) → disable all, then re-enable one at a time to isolate the problem extension",
1285 "Disable hardware acceleration if the browser is crashing or displaying glitches: Chrome/Edge → Settings → System → turn off 'Use hardware acceleration when available' → relaunch",
1286 "Reset the browser profile as a last resort: Chrome → chrome://settings/resetProfileSettings; Edge → edge://settings/resetProfileSettings — this removes extensions and preferences but keeps bookmarks",
1287 "For 'browser not opening' after a Windows update: run hematite --inspect browser_health to check for WebView2 runtime issues; reinstall WebView2 from microsoft.com/en-us/edge/webview2 if it is missing",
1288 "Update the browser: Chrome/Edge → menu (⋮) → Help → About → it will auto-update if behind; Firefox → menu → Help → About Firefox",
1289 "Check if a browser policy is locking settings: run hematite --inspect browser_health and look for 'Policy:' entries — corporate or malware-deployed policies can prevent changes and cause slowness",
1290 ],
1291 dig_deeper: Some("browser_health"),
1292 },
1293 },
1294
1295 RecipeEntry {
1297 triggers: &[
1298 "startup takes", "long boot time", "slow to start up", "boot is slow",
1299 "computer is slow to start", "windows loads slowly", "pc takes forever to boot",
1300 "startup items high impact", "many startup programs", "takes forever to start",
1301 "slow to boot up", "boot time is",
1302 ],
1303 recipe: Recipe {
1304 severity: "INVESTIGATE",
1305 title: "Windows startup is slow — PC takes a long time to boot",
1306 steps: &[
1307 "Open Task Manager (Ctrl+Shift+Esc) → Startup tab → disable 'High impact' programs you don't need at login (RGB controllers, game launchers, chat apps are common culprits)",
1308 "Run hematite --inspect startup_items to see the full list of programs set to run at login",
1309 "Disable Fast Startup if the machine feels slow or unreliable after restarting: Settings → System → Power & sleep → Additional power settings → Choose what the power buttons do → uncheck 'Turn on fast startup' → Save changes",
1310 "Run an SFC scan if slow boot started suddenly (corrupted system files delay boot): PowerShell (admin) → sfc /scannow — then DISM /Online /Cleanup-Image /RestoreHealth to repair the component store",
1311 "Check disk health — a failing or near-full HDD is the most common hidden cause of slow boot: run hematite --inspect disk_health and hematite --inspect storage",
1312 "Check recent Windows Updates: Settings → Windows Update → View update history — if slowness started after a specific update, note the KB number and consider rolling it back (Settings → Update history → Uninstall updates)",
1313 "Check for malware that runs at startup: run hematite --inspect security then a full Defender scan — malware processes running at boot significantly extend startup time",
1314 "For laptops: check the active power plan (Settings → Power & sleep → Additional power settings) — 'Power saver' throttles boot-time CPU speed; switch to 'Balanced' or 'High performance'",
1315 ],
1316 dig_deeper: Some("startup_items"),
1317 },
1318 },
1319
1320 RecipeEntry {
1322 triggers: &[
1325 "update error 0x", "0x8024a105", "0x800705b4", "0x80070422", "0x8024",
1326 "update failed to install", "update stuck downloading", "update downloading at 0%",
1327 "update keeps failing", "cumulative update failed", "feature update failed",
1328 "update rollback failed", "failed to configure windows updates",
1329 "update install failed",
1330 ],
1331 recipe: Recipe {
1332 severity: "ACTION",
1333 title: "Windows Update stuck downloading or failing with an error code",
1334 steps: &[
1335 "Run the built-in troubleshooter first: Settings → Update & Security → Troubleshoot → Additional troubleshooters → Windows Update → Run the troubleshooter — it fixes most common stuck states automatically",
1336 "Reset the Windows Update cache (most effective fix for stuck downloads): PowerShell (admin) → net stop wuauserv → net stop bits → Remove-Item C:\\Windows\\SoftwareDistribution\\* -Recurse -Force → net start wuauserv → net start bits — then check for updates again",
1337 "Free up disk space — updates require 10+ GB free: run hematite --inspect storage; if space is low, empty the Recycle Bin and run Disk Cleanup (cleanmgr.exe) before retrying",
1338 "Repair the Windows component store if DISM errors appear: PowerShell (admin) → DISM /Online /Cleanup-Image /RestoreHealth (takes 5–15 min) → then sfc /scannow → then retry the update",
1339 "For error 0x80070422 (service disabled): Services (services.msc) → find 'Windows Update' → right-click → Properties → set Startup type to 'Automatic' → click Start",
1340 "For error 0x8024a105 or updates stuck at 0%: restart the update services — run hematite --fix 'Windows Update broken' for the automated service restart steps",
1341 "Manually install stuck updates: go to Settings → Windows Update → View update history → note the failing KB number → download it from catalog.update.microsoft.com and run the installer directly",
1342 "If nothing works: the Windows Update Reset Script resets all update components — download from microsoft.com/en-us/download/details.aspx?id=25232 and run as Administrator",
1343 ],
1344 dig_deeper: Some("updates"),
1345 },
1346 },
1347
1348 RecipeEntry {
1352 triggers: &[
1353 "access denied", "you don't have permission",
1354 "you do not have permission", "cannot access this folder",
1355 "permission denied", "unable to access",
1356 "folder access denied", "unauthorized access",
1357 ],
1358 recipe: Recipe {
1359 severity: "INVESTIGATE",
1360 title: "Access denied — file or folder permission error",
1361 steps: &[
1362 "Try running the application as Administrator: right-click the app → Run as administrator — many system folders require elevated permissions",
1363 "Take ownership of the file or folder: right-click the file/folder → Properties → Security tab → Advanced → Owner → Edit → change owner to your account → check 'Replace owner on subcontainers and objects' → OK",
1364 "Grant your account full control: Properties → Security → Edit → Add → type your username → check Full Control → OK; then retry the operation",
1365 "For files on an external drive or from another PC: the old security identifier (SID) from the previous system owns the files — take ownership as above; alternatively, right-click the drive root and grant your account permissions there",
1366 "For network shares: check that your account has read/write permissions on the share — contact the share owner or IT admin to verify permissions",
1367 "For C:\\Windows or system folders: these are locked by design for security; use the built-in Administrator account (net user administrator /active:yes in an elevated command prompt) only if absolutely necessary",
1368 "Check if the file is in use by another process: Task Manager (Ctrl+Shift+Esc) → Details tab → right-click → End task for the process holding the file; or use Sysinternals Process Explorer → Find Handle to locate which process has the lock",
1369 "Run hematite --inspect user_accounts to verify your account type — Standard users cannot access certain folders that Administrators can",
1370 ],
1371 dig_deeper: Some("user_accounts"),
1372 },
1373 },
1374
1375 RecipeEntry {
1377 triggers: &[
1378 "wifi disconnects", "wifi keeps dropping", "wifi keeps disconnecting",
1379 "internet keeps cutting out", "wifi unstable", "wifi drops every",
1380 "internet drops", "connection drops", "wifi connection drops",
1381 "network keeps disconnecting", "wifi intermittent",
1382 ],
1383 recipe: Recipe {
1384 severity: "INVESTIGATE",
1385 title: "Wi-Fi keeps disconnecting or dropping intermittently",
1386 steps: &[
1387 "Run hematite --inspect wifi to check signal strength and negotiated speed — a weak signal (RSSI worse than -70 dBm) is the most common cause of intermittent drops; move closer to the router or use a Wi-Fi extender",
1388 "Disable Wi-Fi adapter power management (the #1 fix for random disconnects): Device Manager → Network Adapters → right-click Wi-Fi adapter → Properties → Power Management → uncheck 'Allow the computer to turn off this device to save power'",
1389 "Update the Wi-Fi driver: Device Manager → Network Adapters → right-click Wi-Fi adapter → Update driver; or download the latest driver from the laptop/motherboard manufacturer's website",
1390 "Forget and rejoin the network: Settings → Network & Internet → Wi-Fi → Manage known networks → select the network → Forget → reconnect and re-enter the password",
1391 "Change the DNS server to a more reliable provider: Settings → Network & Internet → Wi-Fi → Hardware properties → DNS server assignment → Manual → IPv4: 1.1.1.1 and 1.0.0.1 (Cloudflare) or 8.8.8.8 and 8.8.4.4 (Google)",
1392 "Check for channel congestion: router admin page (usually 192.168.1.1) → change the Wi-Fi channel to a less congested one (1, 6, or 11 for 2.4 GHz; any non-overlapping channel for 5 GHz)",
1393 "Reset the TCP/IP stack if drops are accompanied by complete connectivity loss: PowerShell (admin) → netsh int ip reset → netsh winsock reset → reboot",
1394 "Check router firmware updates — outdated router firmware causes intermittent disconnections; update via the router's admin interface",
1395 ],
1396 dig_deeper: Some("wifi"),
1397 },
1398 },
1399
1400 RecipeEntry {
1404 triggers: &[
1405 "nvlddmkm.sys", "nvlddmkm", "amdkmdag.sys", "amdkmdag", "atikmpag.sys",
1406 "dxgkrnl.sys", "tdr failure", "video_tdr_failure", "gpu driver crash",
1407 "gpu driver stopped", "graphics driver stopped", "video hardware error",
1408 "gpu hang", "display adapter error code 43",
1409 ],
1410 recipe: Recipe {
1411 severity: "ACTION",
1412 title: "GPU or display driver crash — TDR failure or black screen",
1413 steps: &[
1414 "Run hematite --inspect device_health to check if the GPU shows a yellow bang in Device Manager (error code 43 = driver failure; error code 45 = device not connected at last boot)",
1415 "Check crash events: run hematite --inspect recent_crashes and look for VIDEO_TDR_FAILURE, nvlddmkm.sys (NVIDIA), or amdkmdag.sys (AMD) in the BSOD list — confirms this is a driver-level crash",
1416 "Update the GPU driver: NVIDIA → download GeForce Experience or go to nvidia.com/drivers; AMD → Radeon Software or amd.com/support — always use the GPU manufacturer's installer, not Windows Update's driver",
1417 "If the crash started after a driver update: roll back the driver — Device Manager → Display Adapters → right-click GPU → Properties → Driver tab → Roll Back Driver",
1418 "For a clean driver reinstall using DDU: boot into Safe Mode (hold Shift + Restart → Troubleshoot → Advanced options → Startup Settings → F4), download Display Driver Uninstaller from guru3d.com, run DDU → Clean and restart, then install the latest driver fresh",
1419 "Check for overheating: run hematite --inspect thermal — GPU TDR failures often happen when the GPU exceeds 90°C; clean the GPU heatsink and reapply thermal paste if temperatures are consistently high",
1420 "Check for unstable overclock: if GPU core clock or VRAM frequency is overclocked via MSI Afterburner or AMD Wattman, restore default clocks — even a small instability at high load can cause TDR crashes",
1421 "As a temporary diagnostic step, raise the TDR delay to confirm TDR is the cause (not a fix): PowerShell (admin) → reg add HKLM\\System\\CurrentControlSet\\Control\\GraphicsDrivers /v TdrDelay /t REG_DWORD /d 8 /f — if crashes stop happening, a driver reinstall or cooling fix will resolve it permanently",
1422 ],
1423 dig_deeper: Some("device_health"),
1424 },
1425 },
1426
1427 RecipeEntry {
1431 triggers: &[
1432 "msmpeng.exe", "msmpeng", "wdnissvc.exe", "wdnissvc",
1433 "defender using high cpu", "defender scan high cpu", "mssense.exe high",
1434 "windows defender high", "defender cpu",
1435 ],
1436 recipe: Recipe {
1437 severity: "INVESTIGATE",
1438 title: "Antimalware Service Executable (MsMpEng.exe) using high CPU",
1439 steps: &[
1440 "Check if a scheduled scan is running: Task Manager (Ctrl+Shift+Esc) → Details → sort by CPU → if MsMpEng.exe is high, open Windows Security → Virus & threat protection → Current threats — let an active scan complete before taking action",
1441 "Exclude the Windows Temp folder and your main development/work directories from real-time scanning: Windows Security → Virus & threat protection → Virus & threat protection settings → Exclusions → Add an exclusion → Folder → add C:\\Windows\\Temp and your project folders",
1442 "Change the scheduled scan time to off-peak hours: Task Scheduler → Microsoft → Windows → Windows Defender → Windows Defender Scheduled Scan → Properties → Triggers → change the time to 3:00 AM or whenever you're not working",
1443 "Disable 'Sample submission' to reduce network-related CPU spikes: Windows Security → Virus & threat protection settings → Automatic sample submission → Off",
1444 "Run hematite --inspect resource_load to confirm MsMpEng is the top CPU consumer — sometimes it's a false lead and a different process (SearchIndexer, WSUS, Windows Update) is the actual culprit",
1445 "Run hematite --inspect security to verify Defender is fully updated — outdated signatures force a more exhaustive scan of each file, significantly increasing CPU usage",
1446 "If the issue is persistent and not during a scan: check for malware that is forcing Defender to constantly rescan itself — run a manual full scan (Windows Security → Full scan) from Safe Mode to clear any persistent threat",
1447 "As a last resort for workstations where Defender conflicts with enterprise AV: use Group Policy to disable MsMpEng real-time monitoring (not recommended on personal machines) — gpedit.msc → Computer Configuration → Administrative Templates → Windows Components → Microsoft Defender Antivirus → Turn off Microsoft Defender Antivirus → Enabled",
1448 ],
1449 dig_deeper: Some("resource_load"),
1450 },
1451 },
1452
1453 RecipeEntry {
1456 triggers: &[
1457 "monitor not detected", "second monitor not showing", "second monitor not detected",
1458 "hdmi not working", "displayport not detected", "display not detected",
1459 "external display not", "no signal on monitor", "monitor not recognized",
1460 "extend display not", "duplicate display not", "monitor shows no signal",
1461 ],
1462 recipe: Recipe {
1463 severity: "INVESTIGATE",
1464 title: "External monitor not detected or showing no signal",
1465 steps: &[
1466 "Press Win+P to open the display projection menu → choose 'Extend' or 'Duplicate' — Windows sometimes stops detecting secondary monitors after sleep or lock",
1467 "Unplug and replug the cable (HDMI or DisplayPort) at both ends — contact issues are the most common cause of 'no signal'; try a different cable if available",
1468 "Run hematite --inspect display_config to see which monitors Windows currently detects and their reported resolution and refresh rate",
1469 "In Display Settings (right-click desktop → Display settings) → scroll down → click 'Detect' under Multiple displays — forces Windows to re-scan for connected monitors",
1470 "Try a different port: if using HDMI 1, try HDMI 2 or the DisplayPort on the same GPU or dock",
1471 "Check if the monitor input source matches: most monitors have an on-screen menu to switch between HDMI 1, HDMI 2, DisplayPort, VGA — cycle through all inputs",
1472 "Update or reinstall the GPU driver: Device Manager → Display Adapters → right-click GPU → Update driver; or use GeForce Experience (NVIDIA) or Radeon Software (AMD) for the latest driver",
1473 "For docks and USB-C hubs: ensure the dock has a DisplayLink or Thunderbolt driver installed and is connected to a Thunderbolt-capable port; generic USB-C ports often don't support video output",
1474 ],
1475 dig_deeper: Some("display_config"),
1476 },
1477 },
1478
1479 RecipeEntry {
1482 triggers: &[
1483 "explorer.exe crash", "explorer.exe not responding", "windows explorer crash",
1484 "file explorer crash", "desktop icons disappeared", "taskbar disappeared",
1485 "taskbar not responding", "start menu not working", "start menu crashed",
1486 "desktop froze", "desktop not responding", "shell infrastructure crash",
1487 ],
1488 recipe: Recipe {
1489 severity: "ACTION",
1490 title: "Windows Explorer / desktop or taskbar crashed",
1491 steps: &[
1492 "Restart Explorer immediately without rebooting: press Ctrl+Shift+Esc → Task Manager → Details tab → find explorer.exe → right-click → End task → File → Run new task → type explorer.exe → OK",
1493 "If Task Manager won't open: press Ctrl+Alt+Del → Task Manager → or run from the lock screen",
1494 "Check for recent Windows Updates or driver updates that may have caused the crash: Settings → Windows Update → View update history — note what installed in the last 48 hours",
1495 "Check the Application event log for crash details: run hematite --inspect log_check and look for 'Windows Explorer' or 'APPCRASH' events near the crash time",
1496 "Run SFC to repair corrupted shell files (a common cause of recurring Explorer crashes): PowerShell (admin) → sfc /scannow → then DISM /Online /Cleanup-Image /RestoreHealth → reboot",
1497 "If Desktop icons keep disappearing: right-click Desktop → View → ensure 'Show desktop icons' is checked",
1498 "If Start menu doesn't work after reboot: PowerShell (admin) → Get-AppXPackage -AllUsers | Foreach {Add-AppxPackage -DisableDevelopmentMode -Register \"$($_.InstallLocation)\\AppXManifest.xml\"} — reinstalls shell UWP components",
1499 "Create a new user profile as a diagnostic: Settings → Accounts → Family & other users → Add someone else — if Explorer works fine in the new profile, your current profile is corrupt",
1500 ],
1501 dig_deeper: Some("log_check"),
1502 },
1503 },
1504
1505 RecipeEntry {
1507 triggers: &[
1508 "application crash event(s)",
1509 "application hang event(s)",
1510 "most-crashed application:",
1511 "wer reports archived",
1512 "faulting module:",
1513 ],
1514 recipe: Recipe {
1515 severity: "ACTION",
1516 title: "Application crash history detected",
1517 steps: &[
1518 "Identify the faulting app and module from the crash list above — the module name tells you whether it's a system DLL, a runtime, or an app-specific component",
1519 "If the faulting module is a system DLL (ntdll.dll, kernelbase.dll): run SFC and DISM — PowerShell (admin): sfc /scannow then DISM /Online /Cleanup-Image /RestoreHealth",
1520 "If the faulting module is a Visual C++ runtime (vcruntime*.dll, msvcp*.dll, vcomp*.dll): download and reinstall all Visual C++ Redistributable packages from microsoft.com/download",
1521 "For the most-crashed app: uninstall it (Settings → Apps), reboot, then reinstall a fresh copy from the publisher — cached corrupted app data often causes repeat crashes",
1522 "Try running the crashing app as Administrator: right-click its shortcut → Run as administrator — some apps need elevation to access resources they depend on",
1523 "Check for conflicting third-party AV or security software injecting into the process: temporarily disable real-time protection and test; if the crash stops, add the app folder to AV exclusions",
1524 "Check for pending Windows Updates: Settings → Windows Update → Check for updates — a pending cumulative update may patch the faulting module",
1525 "Run hematite --inspect recent_crashes to also check for BSOD events — kernel crashes near the same time as app crashes often share a root cause (bad driver, failing RAM)",
1526 ],
1527 dig_deeper: Some("app_crashes"),
1528 },
1529 },
1530
1531 RecipeEntry {
1533 triggers: &[
1534 "resiliencydisableditems:",
1535 "outlook's crash resiliency has auto-disabled",
1536 "active outlook add-ins detected — add-in overload",
1537 "add-in pressure, large ost files",
1538 "large ost files can cause outlook slowness",
1539 "application error |",
1540 "recent outlook crash evidence found",
1541 ],
1542 recipe: Recipe {
1543 severity: "ACTION",
1544 title: "Outlook add-in crash or OST / memory pressure",
1545 steps: &[
1546 "Start Outlook in safe mode to confirm add-ins are the cause: hold Ctrl and click the Outlook icon (or run: outlook.exe /safe) — if Outlook works fine in safe mode, an add-in is crashing it",
1547 "Identify and remove the crashing add-in: File → Options → Add-ins → Manage: COM Add-ins → Go → uncheck add-ins one at a time, restarting between each to find the culprit",
1548 "Clear resiliency-disabled add-ins from the registry: in PowerShell (admin) → Remove-Item 'HKCU:\\Software\\Microsoft\\Office\\16.0\\Outlook\\Resiliency\\DisabledItems' -Recurse -ErrorAction SilentlyContinue — then re-enable your needed add-ins",
1549 "If Outlook RAM is very high (1500+ MB): a large or corrupt OST file is the likely cause — in Outlook: File → Account Settings → Account Settings → Data Files → select the OST → open file location, close Outlook, rename the OST to .old, then reopen Outlook (it rebuilds from the server)",
1550 "Repair the Office installation: Control Panel → Programs → Microsoft 365 → Change → Quick Repair (fast), then Online Repair (thorough, requires internet) if Quick Repair doesn't fix it",
1551 "Check the Application event log for the faulting module: run hematite --inspect app_crashes and filter for OUTLOOK.EXE — this shows which DLL (often a third-party add-in or mso.dll) is faulting",
1552 "Update all Office add-ins: COM add-ins from vendors (Grammarly, Adobe, Zoom) often break after major Office updates — download the latest version of each from the vendor's website",
1553 ],
1554 dig_deeper: Some("outlook"),
1555 },
1556 },
1557];
1558
1559pub struct HealthScore {
1560 pub grade: char,
1561 pub label: &'static str,
1562 pub action_count: usize,
1563 pub investigate_count: usize,
1564 pub monitor_count: usize,
1565}
1566
1567impl HealthScore {
1568 pub fn summary_line(&self) -> String {
1569 match (
1570 self.action_count,
1571 self.investigate_count,
1572 self.monitor_count,
1573 ) {
1574 (0, 0, 0) => "No issues found — machine is healthy.".to_string(),
1575 (0, 0, m) => format!("{} item(s) to monitor.", m),
1576 (0, i, 0) => format!("{} item(s) need investigation.", i),
1577 (0, i, m) => format!("{} item(s) need investigation, {} to monitor.", i, m),
1578 (a, 0, 0) => format!("{} item(s) require immediate action.", a),
1579 (a, i, _) => format!(
1580 "{} item(s) require immediate action, {} need investigation.",
1581 a, i
1582 ),
1583 }
1584 }
1585
1586 pub fn grade_intro(&self) -> &'static str {
1589 match self.grade {
1590 'A' => "Your PC is in great shape — no issues were found. The diagnostic data below is included for reference.",
1591 'B' => "Your PC is doing well, but there's one thing worth a closer look. The action plan below has specific steps.",
1592 'C' => "Your PC needs some attention. A couple of things should be investigated — follow the action plan below.",
1593 'D' => "Your PC needs attention. There are issues that should be fixed — follow the action plan below.",
1594 _ => "Your PC has critical issues that need immediate attention. Work through the action plan below as soon as possible.",
1595 }
1596 }
1597}
1598
1599pub fn score_health(outputs: &[(&str, &str)]) -> HealthScore {
1601 let all_recipes = collect_unique_recipes(outputs);
1602
1603 let action_count = all_recipes
1604 .iter()
1605 .filter(|r| r.severity == "ACTION")
1606 .count();
1607 let investigate_count = all_recipes
1608 .iter()
1609 .filter(|r| r.severity == "INVESTIGATE")
1610 .count();
1611 let monitor_count = all_recipes
1612 .iter()
1613 .filter(|r| r.severity == "MONITOR")
1614 .count();
1615
1616 let (grade, label) = if action_count >= 3 {
1617 ('F', "Critical")
1618 } else if action_count >= 1 {
1619 ('D', "Poor")
1620 } else if investigate_count >= 2 {
1621 ('C', "Fair")
1622 } else if investigate_count >= 1 {
1623 ('B', "Good")
1624 } else {
1625 ('A', "Excellent")
1626 };
1627
1628 HealthScore {
1629 grade,
1630 label,
1631 action_count,
1632 investigate_count,
1633 monitor_count,
1634 }
1635}
1636
1637pub fn format_action_plan(outputs: &[(&str, &str)]) -> String {
1640 let mut all_recipes = collect_unique_recipes(outputs);
1641
1642 if all_recipes.is_empty() {
1643 return "No actionable findings — machine appears healthy.\n".to_string();
1644 }
1645
1646 all_recipes.sort_by_key(|r| match r.severity {
1648 "ACTION" => 0,
1649 "INVESTIGATE" => 1,
1650 _ => 2,
1651 });
1652
1653 let mut out = String::with_capacity(all_recipes.len() * 200);
1654 for (i, recipe) in all_recipes.iter().enumerate() {
1655 let badge = match recipe.severity {
1656 "ACTION" => "⚠ ACTION REQUIRED",
1657 "INVESTIGATE" => "🔍 INVESTIGATE",
1658 _ => "📊 MONITOR",
1659 };
1660 let _ = write!(out, "### {}. {} — {}\n\n", i + 1, badge, recipe.title);
1661 for step in recipe.steps {
1662 out.push_str("- ");
1663 out.push_str(step);
1664 out.push('\n');
1665 }
1666 if let Some(_topic) = recipe.dig_deeper {
1667 out.push_str("\n*Run `hematite --diagnose` for a deeper automated investigation.*\n");
1668 }
1669 out.push('\n');
1670 }
1671
1672 out
1673}
1674
1675pub fn format_action_plan_html(outputs: &[(&str, &str)]) -> String {
1677 let mut all_recipes = collect_unique_recipes(outputs);
1678
1679 if all_recipes.is_empty() {
1680 return "<p class=\"healthy\">No actionable findings — machine appears healthy.</p>\n"
1681 .to_string();
1682 }
1683
1684 all_recipes.sort_by_key(|r| match r.severity {
1685 "ACTION" => 0,
1686 "INVESTIGATE" => 1,
1687 _ => 2,
1688 });
1689
1690 let mut out = String::with_capacity(all_recipes.len() * 400);
1691 for (i, recipe) in all_recipes.iter().enumerate() {
1692 let (sev_class, badge_class, badge_text) = match recipe.severity {
1693 "ACTION" => ("sev-action", "b-action", "ACTION REQUIRED"),
1694 "INVESTIGATE" => ("sev-investigate", "b-investigate", "INVESTIGATE"),
1695 _ => ("sev-monitor", "b-monitor", "MONITOR"),
1696 };
1697 let _ = writeln!(out, "<div class=\"recipe {}\">", sev_class);
1698 let _ = writeln!(
1699 out,
1700 "<h3><span class=\"badge {}\">{}</span> {}. {}</h3>",
1701 badge_class,
1702 badge_text,
1703 i + 1,
1704 he(recipe.title)
1705 );
1706 out.push_str("<ol>\n");
1707 for step in recipe.steps {
1708 let _ = writeln!(out, "<li>{}</li>", he(step));
1709 }
1710 out.push_str("</ol>\n");
1711 if let Some(_topic) = recipe.dig_deeper {
1712 out.push_str(
1713 "<p class=\"dig-deeper\">Run <code>hematite --diagnose</code> for a deeper automated investigation of this issue.</p>\n"
1714 );
1715 }
1716 out.push_str("</div>\n");
1717 }
1718 out
1719}
1720
1721use crate::agent::html_template::he;