Tech Debt Verification & Analysis
Internal Document
Re-verified against v1.2.0 source — August 2026. This supersedes the June 2026 verification. All line counts, method counts, and locations were re-measured against the current tree; the summary table reflects the live status of every item.
⚠️ Post-verification update (Aug 2026): The
XboxDeviceServicegod class item in this report is RESOLVED — it was split into 6 domain services and deleted after this verification ran.FileExplorerViewModelremains large (~1,736 lines). See current Tech Debt.
Verification Results
HIGH SEVERITY
🔴 VERIFIED #1: XboxDeviceService — God Class (WORSE)
| Aspect | June 2026 | Aug 2026 (v1.2.0) |
|---|---|---|
| File | XBVault/Services/XboxDeviceService.cs | unchanged |
| Lines | 1,207 | 1,433 (+226) |
| Public members | 35 | ~41 |
| Cyclomatic complexity | not measured | 205 |
| IDisposable | ❌ | ❌ still absent |
| Domains mixed | 8 | 8 |
Status: OPEN — grew 19% in two months. Split recommendation still valid (XboxPackageService / XboxProcessService / XboxCrashService / XboxNetworkService / XboxSystemService / XboxPerformanceService).
Effort Estimate: 6–8 hours
🔴 VERIFIED #2 (NEW): FileExplorerViewModel — Undocumented God Class
| Aspect | Finding |
|---|---|
| File | XBVault/ViewModels/FileExplorerViewModel.cs |
| Lines | 1,880 — largest file in the repository |
| Cyclomatic complexity | 254 — highest in the project |
| Responsibilities | SFTP browse/upload (folder + mixed), drive mounting, path parsing, drag-drop, UI state |
Status: OPEN — untracked until this verification. Surpassed XboxDeviceService as the biggest single file.
Recommendation: Split upload pipelines into SftpUploadService; extract path normalization; keep VM for state/wiring only.
Effort Estimate: 6–8 hours
✅ VERIFIED #3: _Backup/ directory tracked in git — RESOLVED
Removed from tracking, gitignored, deleted. Confirmed no Assets/_Backup/ in tree.
MEDIUM SEVERITY
🟡 VERIFIED #4: App.axaml.cs — 724 lines, manual composition root (PARTIAL)
| Aspect | June 2026 | Aug 2026 (v1.2.0) |
|---|---|---|
| Total lines | 497 | 724 |
Bare catch { } in ShowErrorDialogSafe |
2 (lines 107/110) | 0 — FIXED (all catch blocks now Logger.Error) |
Manual new service wiring |
yes | yes (6 services) |
| DI container | none | none (0 ServiceProvider/AddSingleton in tree) |
Status: PARTIAL — the silent-catch defect is resolved, but the composition-root bloat grew and remains unaddressed.
Effort Estimate: 3–5 hours
🟡 VERIFIED #5: No ConfigureAwait(false) Anywhere (WORSE)
| Aspect | June 2026 | Aug 2026 (v1.2.0) |
|---|---|---|
| Total await calls | ~82–100 (Services) | ~404 (Services + ViewModels) |
| ConfigureAwait(false) | 0 | 0 |
Status: OPEN — the surface area quadrupled while the gap stayed.
Effort Estimate: 1–2 hours (mechanical)
🟡 VERIFIED #6: Silent Exception Swallowing — 26 bare catches
| Category | Count | Verdict |
|---|---|---|
| Intentional (Logger self-protection, Sftp disconnect + trace, Program.cs last-resort, JSON parse guards) | ~15 | ✅ OK |
| Needs audit (FileExplorerViewModel:1835, InstalledViewModel:521/543, ErrorDialog:145/157, FileExplorerView:601, BoolToValueConverter:18) | ~7 | ⚠️ flagged in #6 |
| JSON parse guards in XboxDeviceService:770–819 (return false) | 4 | ⚠️ suggest Logger.Trace |
Status: PARTIAL — the 10 originally-documented sites were fixed (v0.9.2), but regressions appeared in code added since.
Effort Estimate: 1 hour
🟡 VERIFIED #7: async void — 22 instances (11 → 22)
| Aspect | June 2026 | Aug 2026 (v1.2.0) |
|---|---|---|
| Instances | 11 | 22 |
| Files | 5 | 11 |
| High-risk (real async work) | 5 | 15 |
New high-risk handlers since June: MainWindow OnDiscordClick/OnDisconnectClick, BrowseView/InspectorView/InstalledView OnDrop, ErrorDialog OnConnectClick/OnDownloadClick, FileExplorerView uploads (5).
Status: OPEN — doubled. Highest crash-risk item after the god classes.
Effort Estimate: 3–5 hours
🟡 VERIFIED #8: IDisposable Not Implemented
| Class | June 2026 | Aug 2026 (v1.2.0) |
|---|---|---|
| XboxDeviceService | ❌ | ❌ still open |
| PerformanceViewModel | ❌ | ✅ : IDisposable, disposes CTS |
| SftpService | — | ✅ : IDisposable |
| XrayAgentService | — | ✅ : IDisposable |
| PackageOverrideService | — | ✅ : IDisposable |
| GitHubReleaseCheckerService | — | ✅ : IDisposable |
Status: PARTIAL — only XboxDeviceService remains. See #1.
Effort Estimate: 1 hour
🟡 VERIFIED #9: Border CornerRadius Does Not Clip Image
Status: OPEN — re-verified: no Clip=/ImageBrush/RectangleGeometry workaround in BrowseView/ItemDetailWindow. Avalonia 12.0.0 limitation stands.
Effort Estimate: 2–3 hours
🟡 VERIFIED #10 (NEW): ViewModels Past the God-Class Threshold
| File | Lines | Complexity |
|---|---|---|
| FileExplorerViewModel | 1,880 | 254 |
| BrowseViewModel | 899 | 167 |
| CustomInstallViewModel | 726 | 98 |
| InstalledViewModel | 632 | 112 |
| InspectorViewModel | 545 | 72 |
Status: OPEN — BrowseViewModel alone grew 580 → 899 since June.
Effort Estimate: 4–8 hours across the set
✅ VERIFIED #11–12: TitleGradient + WindowCloseButton — RESOLVED (v0.9.1)
Confirmed shared resources in BladesTheme.axaml.
LOW SEVERITY
✅ VERIFIED #13: Magic Delays — MOSTLY RESOLVED
Named constants cover the bulk. 2 stragglers: DialogFadeBehavior.cs:53 (200), CustomInstallViewModel.cs:550/566 (1500).
Effort Estimate: 15 min
✅ VERIFIED #14: CatalogApiService injection — RESOLVED
BrowseViewModel.cs:50 constructor receives CatalogApiService. Self-instantiation gone.
✅ VERIFIED #15: PerformanceViewModel CTS — RESOLVED
PerformanceViewModel.cs:18–21 implements IDisposable, calls _cts?.Dispose().
✅ VERIFIED #16: DllImport / System.Management — RESOLVED
csproj defines WINDOWS_BUILD on Windows only; UsbDriveDetector WMI wrapped in #if WINDOWS_BUILD.
✅ VERIFIED #17: PerformanceSnapshot silent catch — RESOLVED
Logs Logger.Error.
🟢 VERIFIED #18: BrowseViewModel size — WORSE (see #10)
✅ VERIFIED #19: Orphaned _Backup icons — RESOLVED (v0.9.1)
🟢 VERIFIED #20: FileExplorer drive list — hardcoded, accepted fallback
Static drive list still in DetectDrivesAsync. Status: sufficiently addressed.
🟢 VERIFIED #21 (NEW): Zero test coverage
No test project in tree. docs/ideas/testing-infrastructure.md proposal exists but unimplemented. Highest-impact gap for enabling the #1/#2/#10 refactors safely.
🟢 VERIFIED #22 (NEW): Comment ratio 0–2%
Services 2%, ViewModels 0%.
Summary Table
| # | Issue | Severity | Status (Aug 2026) | Effort |
|---|---|---|---|---|
| 1 | God class (XboxDeviceService) | 🔴 High | ⚠️ WORSE — 1,433 lines, cplx 205 | 6–8h |
| 2 | God class (FileExplorerViewModel) | 🔴 High | ❌ NEW — 1,880 lines, cplx 254 | 6–8h |
| 3 | _Backup directory | 🔴 High | ✅ Resolved | — |
| 4 | App.axaml.cs bloat | 🟡 Med | ⚠️ Partial (catches fixed, root open) | 3–5h |
| 5 | No ConfigureAwait | 🟡 Med | ⚠️ WORSE — 404 awaits, 0 configured | 1–2h |
| 6 | Silent exceptions | 🟡 Med | ⚠️ Partial — 26 sites, ~7 to audit | 1h |
| 7 | async void (11→22) | 🟡 Med | ⚠️ WORSE — 22 instances | 3–5h |
| 8 | No IDisposable | 🟡 Med | ⚠️ Partial — only XboxDeviceService left | 1h |
| 9 | Border clipping | 🟡 Med | ❌ Open | 2–3h |
| 10 | Large ViewModels | 🟡 Med | ❌ NEW — 5 files > 500 lines | 4–8h |
| 11 | Gradient duplication | 🟡 Med | ✅ Resolved | — |
| 12 | Button duplication | 🟡 Med | ✅ Resolved | — |
| 13 | Magic delays | 🟢 Low | ✅ Mostly resolved (2 stragglers) | 15m |
| 14 | CatalogApiService injection | 🟢 Low | ✅ Resolved | — |
| 15 | CTS disposal | 🟢 Low | ✅ Resolved | — |
| 16 | DllImport/Windows deps | 🟢 Low | ✅ Resolved | — |
| 17 | PerformanceSnapshot | 🟢 Low | ✅ Resolved | — |
| 18 | BrowseViewModel size | 🟢 Low | ⚠️ WORSE — 899 lines | (see #10) |
| 19 | Orphaned icons | 🟢 Low | ✅ Resolved | — |
| 20 | Drive list hardcoded | 🟢 Low | ➖ Accepted (fallback OK) | — |
| 21 | Zero tests | 🟢 Low | ❌ Open — highest impact gap | 8–16h |
| 22 | Comment ratio 0–2% | 🟢 Low | ❌ Open | 0h (during refactors) |
Recommended Priority for Fixes (updated Aug 2026)
- IMMEDIATE: Add test infrastructure (
dotnet test+ CI step) before any large refactor — makes #2 and #3 safe. - HIGH: Split
FileExplorerViewModel(largest file, 254 complexity) — biggest risk concentration in the app. - HIGH: Split
XboxDeviceService(+ implementIDisposablewhile touching it). - HIGH: Eliminate the 15 high-risk
async voidhandlers (FireAndForget wrapper). - MEDIUM: Add
.ConfigureAwait(false)to service layer. - MEDIUM: Audit the ~7 flagged bare-catch sites.
- LOW: Straggler magic delays, comment-why on refactored paths.
Document version: 3.0
Last updated: 2026-08-01
Status: Complete re-verification against v1.2.0