# SnapBack Extension UI Implementation Audit Report

**Audit Date:** January 30, 2026
**Auditor:** Claude (AI-Assisted Audit)
**Scope:** `/apps/vscode/src/` - VS Code Extension
**Reference Spec:** `docs/implementation/extension/new_extension_spec.md`

---

## Executive Summary

This audit evaluates the SnapBack VS Code extension's UI implementation against the spec's core philosophy: **"Invisible until needed."** The extension is designed as a recovery tool, not a monitoring dashboard, optimized for "oh no" moments.

### Overall Assessment

| Phase | Status | Score |
|-------|--------|-------|
| Phase 0: Foundation | ✅ PASS | 85% |
| Phase 1: Status Bar & Quick Actions | ⚠️ PARTIAL | 72% |
| Phase 2: Recovery Timeline Tree | ✅ PASS | 88% |
| Phase 3: Editor Integration | ❌ NEEDS WORK | 26% |
| Phase 4: Testing & Rollout | ✅ PASS | 85% |

**Key Findings:**
- ✅ All 7 requested commands implemented
- ✅ Robust state machine architecture with feature flags
- ✅ Comprehensive testing infrastructure (598 test files)
- ⚠️ Status bar uses 8-state FSM vs. spec's 4-state requirement
- ❌ Editor decorations missing time filtering, gutter icons, and command links
- ❌ Pre-restore undo snapshot not implemented (critical safety gap)

**Truth source:** This audit supersedes any prior UI audits for the VS Code extension; all future UI PRs that touch the extension UI must reference at least one roadmap item ID from Part II of this document.

### How to Use This Document

- **For planning**: Pick a Priority bucket in Part II and turn each roadmap row (by ID) into a ticket in your tracker. Each ticket must reference its roadmap item ID (for example, `P1-SB-STATE-SEMANTICS`).
- **For reviewing PRs**: For any PR that changes UI behavior, verify that it references at least one roadmap item ID and that the changed files and tests satisfy that item’s acceptance criteria while updating any relevant "Expected vs Actual" tables in Part I.

### Priority Legend

| Priority | Meaning |
|----------|---------|
| P1 | Safety or semantic break that can cause data loss or fundamentally mislead users. |
| P2 | UX or performance issue that degrades experience but has safe fallbacks. |
| P3 | Polish and clarity improvements that significantly improve usability. |
| P4 | Edge-case or maintenance items, including long-session performance and cleanup. |

---

## Part I: Implementation Audit

## 🛑 Pre-Audit Verification

### Philosophy Verification

| Checkbox | Status | Evidence |
|----------|--------|----------|
| ✅ Read implementation spec | VERIFIED | `docs/implementation/extension/new_extension_spec.md` |
| ✅ Understand core philosophy | VERIFIED | "Invisible until needed" principle documented |
| ✅ Articulate why NOT building "Protected Files" view | VERIFIED | Spec explicitly excludes this (shows plumbing, creates anxiety) |
| ✅ Access to existing codebase | VERIFIED | Full codebase explored |

### Spec Location
The implementation spec exists at:
- `docs/implementation/extension/new_extension_spec.md` (1,378 lines)
- `docs/implementation/extension/revised_tree_view.md` (1,448 lines)

---

## Phase 0: Foundation Audit

### 0.1 Existing Infrastructure Reuse

| Component | Location | Key Methods | Delegates to Daemon |
|-----------|----------|-------------|---------------------|
| **SnapshotContentProvider** | `src/providers/SnapshotContentProvider.ts` | `provideTextDocumentContent()`, LRU cache | Via `IStorageManager` ✅ |
| **WorkspaceDataService** | `src/services/workspace-data/WorkspaceDataService.ts` | Factory pattern, 5 composed services | Via `DaemonBridge` ✅ |
| **OperationCoordinator** | `src/operationCoordinator.ts` (56KB) | `coordinateSnapshotCreation()`, `restoreToSnapshot()` | Via `IStorageManager`, `SessionCoordinator` ✅ |
| **SnapshotDocumentProvider** | `src/providers/SnapshotDocumentProvider.ts` | Legacy provider | ⚠️ DEPRECATED - uses local Map cache |

**URI Schemes:**
- **Active:** `snapback://<snapshotId>/<encodedFilePath>`
- **Deprecated:** `snapback-snapshot:<filePath>` (should be consolidated)

**Verdict:** ✅ **PASS** - Infrastructure properly delegates to daemon. Deprecated provider needs migration.

### 0.2 Interface Contract Verification

| Interface | Status | Location |
|-----------|--------|----------|
| `IRecoveryService` | ✅ DEFINED | `src/services/recovery/interfaces.ts` |
| `ISessionStatsProvider` | ✅ DEFINED | `src/services/recovery/interfaces.ts` |
| Event patterns | ✅ Uses `vscode.Event<T>` | Throughout codebase |
| No `any` types in public interfaces | ✅ VERIFIED | Types use proper generics |

**Verdict:** ✅ **PASS** - Interfaces defined correctly.

### 0.3 FSM State Migration

**Current Implementation:** 8-state FSM with simplified 4-state behind feature flag

| Legacy State | Maps To | Notes |
|--------------|---------|-------|
| `idle` | `idle` | Default state |
| `protected` | `protected` | Flash state, 3s auto-revert |
| `ambient-risk` | `alert` | Consolidated |
| `recommend` | `alert` | Consolidated |
| `critical` | `alert` | Consolidated |
| `recovering` | `error` | Consolidated |
| `error` | `error` | System error |
| `disabled` | `error` | User disabled |

**Feature Flag:** `snapback.ui.simplifiedStatusBar` (default: `false`)

**Issue:** Spec requires 4 states: `active (✓ + count)`, `paused (⏸)`, `warning (⚠️)`, `error (✗)`. Current simplified FSM uses different semantics (risk-based vs. activity-based).

**Verdict:** ⚠️ **PARTIAL** - Mapping exists but semantics differ from spec.

### 0.4 URI Scheme Decision

| Scheme | Status | Usage |
|--------|--------|-------|
| `snapback://` | ✅ ACTIVE | SnapshotContentProvider, diff views |
| `snapback-snapshot:` | ⚠️ DEPRECATED | SnapshotDocumentProvider (legacy) |

**Verdict:** ⚠️ **CONSOLIDATION NEEDED** - Deprecated scheme should be migrated.

---

## Phase 1: Status Bar & Quick Actions Audit

### 1.1 Status Bar Implementation

#### Philosophy Check

| Requirement | Status | Evidence |
|-------------|--------|----------|
| Shows ONLY 4 states | ❌ FAIL | 8 states in production, 4-state behind feature flag |
| No additional states | ❌ FAIL | Has `ai-active`, `vitals`, `recommendation` states |
| No "verification" states | ✅ PASS | No "checking" or "verifying" states |
| No promotional messages | ✅ PASS | No upsell messages in status bar |

#### Performance Check

| Budget | Implementation | Status |
|--------|----------------|--------|
| Render < 16ms (p95) | Not measured in status bar | ⚠️ NOT VERIFIED |
| Debouncing ≥ 100ms | 1500ms sequence debounce | ✅ PASS (exceeds) |
| Performance telemetry | Logging with `[SB:STATUS]` tags | ✅ PASS |
| No sync I/O in render | Async patterns used | ✅ PASS |

#### Code Quality

| Requirement | Status | Evidence |
|-------------|--------|----------|
| ThemeColor used | ⚠️ PARTIAL | `StatusBarManager.ts` uses ThemeColor; `SimplifiedStatusBarStateMachine.ts` has hardcoded hex colors (`#4ade80`, `#f97316`, `#ef4444`) |
| Codicons used | ✅ PASS | Uses `$(shield-check)`, `$(shield-alert)`, `$(shield-x)` |
| Telemetry snake_case | ⚠️ PARTIAL | Mixed dot-notation and snake_case |

**Verdict:** ⚠️ **PARTIAL PASS** - Core functionality works but state model differs from spec.

#### Status Bar State Semantics (P1-SB-STATE-SEMANTICS)

The spec defines an activity-based state model, while the simplified implementation uses a risk-based model. This creates a semantic mismatch between what users expect to see and what the status bar actually communicates.

| State | Expected (Spec) | Actual (Implementation) | Priority |
|-------|-----------------|-------------------------|----------|
| active | `SnapBack ✓ <count>` showing session snapshot count during normal operation | No dedicated `active` state; `idle` is used when no risk is detected and does not show a snapshot count | P1 |
| paused | `SnapBack ⏸` indicating user-disabled protection | No `paused` state; disabled maps to `error`, conflating user choice with failure | P1 |
| warning | `SnapBack ⚠️` indicating issues detected while the system is still operating | `alert` state is risk-based and does not follow the spec’s activity semantics | P1 |
| error | `SnapBack ✗` indicating system failure | `error` state exists but shares semantics with both user-disabled and failure cases | P1 |

This semantic gap breaks the user mental model of "Is SnapBack working?" and must be resolved either by aligning the implementation to the spec’s four-state model or by explicitly updating the spec to document a risk-based model and adjusting user-facing copy accordingly.

### 1.2 Quick Actions Panel

#### Philosophy Check

| Requirement | Status | Evidence |
|-------------|--------|----------|
| Shows ONLY last 5 changed files | ✅ PASS | `getRecent(5)` in implementation |
| Session stats summary only | ✅ PASS | Duration + snapshot count |
| NO "Protected Files" action | ✅ PASS | Not present |
| NO "Verify Protection" action | ✅ PASS | Not present |

#### Required Actions

| Action | Status |
|--------|--------|
| "Undo Recent Changes" → recovery timeline | ✅ IMPLEMENTED |
| "Open Recovery Timeline" → tree view | ✅ IMPLEMENTED |
| "Open Dashboard" → external URL | ✅ IMPLEMENTED |
| File items → diff view | ✅ IMPLEMENTED |

#### Performance Check

| Budget | Status | Notes |
|--------|--------|-------|
| Panel < 100ms | ✅ TESTED | Performance tests exist |
| Async snapshot fetch | ✅ PASS | Non-blocking |
| Loading state | ✅ PASS | Shows loading indicator |

**Verdict:** ✅ **PASS**

### 1.3 Recovery Commands

#### Command Registration

| Command | Status |
|---------|--------|
| `snapback.showRecentChanges` | ✅ REGISTERED |
| `snapback.showQuickActions` | ✅ REGISTERED |
| `snapback.openRecoveryTimeline` | ✅ REGISTERED |
| `snapback.compareWithSnapshot` | ✅ REGISTERED |
| `snapback.restoreFromSnapshot` | ✅ REGISTERED |
| `snapback.openDashboard` | ✅ REGISTERED |
| `snapback.restoreAllRecent` | ✅ REGISTERED |

**All 7 requested commands are implemented.**

#### Keyboard Shortcut Check

| Shortcut | Status | Notes |
|----------|--------|-------|
| Cmd+Shift+Z | ✅ NOT USED | No conflict with Redo (good!) |
| Cmd+Alt+Z | ✅ USED | Main restore command |
| Cmd+Shift+R | ✅ USED | Quick restore |

**Verdict:** ✅ **PASS** - No Redo conflict.

#### Restore Flow Check

| Requirement | Status | Evidence |
|-------------|--------|----------|
| Creates undo snapshot BEFORE restoring | ❌ **CRITICAL FAIL** | No pre-restore snapshot creation in `SnapshotRestoreUI.ts` |
| "Compare First" option | ✅ PASS | Present in recovery commands |
| Success notification with "Undo" | ⚠️ PARTIAL | Button exists but `snapback.undoLastRestore` command is **NOT REGISTERED** |
| Batch restore shows file count | ✅ PASS | Modal shows count |
| Delegates to daemon | ✅ PASS | Via `OperationCoordinator` |

**Critical Issue:** Users can lose their pre-restore state if they want to undo the restoration.

**Verdict:** ❌ **CRITICAL ISSUE** - Pre-restore safety gap.

### 1.4 Notification System

| Requirement | Status | Evidence |
|-------------|--------|----------|
| NO promotional notifications | ✅ PASS | No upsell in notifications |
| NO frequent status updates | ✅ PASS | Debounced |
| 5-minute deduplication | ✅ PASS | `shownNotifications` Map with TTL |
| "Do not show again" option | ✅ PASS | On dismissible notifications |

**Verdict:** ✅ **PASS**

**Memory & Lifetime (P4-NOTIFICATIONS-MAP-CLEANUP):** The `shownNotifications: Map<string, number>` deduplication structure must periodically drop expired entries to avoid unbounded growth; current behavior checks TTL before showing notifications but never removes expired entries, so a follow-up change should prune entries older than 5 minutes on a timer.

---

## Phase 2: Recovery Timeline Tree Audit

### 2.1 Tree Structure

#### Philosophy Check

| Requirement | Status | Evidence |
|-------------|--------|----------|
| Tree COLLAPSED by default | ✅ PASS | Only "Last 15 Minutes" expanded |
| Time → file → snapshot hierarchy | ✅ PASS | Three-level structure |
| NO "Protected Files" grouping | ✅ PASS | Not present |
| NO MCP client grouping | ✅ PASS | Reserved for dashboard |

#### Time Groups

| Group | Status |
|-------|--------|
| "Last 15 Minutes" (expanded) | ✅ IMPLEMENTED |
| "Earlier This Session" (collapsed) | ✅ IMPLEMENTED |
| "Previous Sessions" (collapsed) | ✅ IMPLEMENTED |

#### Lazy Loading

| Requirement | Status |
|-------------|--------|
| Root level on tree open | ✅ PASS |
| Files on time group expand | ✅ PASS |
| Snapshots on file expand | ✅ PASS |
| No eager loading | ✅ PASS |

**Verdict:** ✅ **PASS**

### 2.2 Tree Item Implementation

#### Context Value Namespacing

| Item Type | Expected | Actual | Status |
|-----------|----------|--------|--------|
| Time group | `snapback:timeGroup` | `snapback.activityGroup` | ⚠️ Dots instead of colons |
| File | `snapback:file` | `snapback.protectedFile` | ⚠️ Dots instead of colons |
| Snapshot | `snapback:snapshot` | `snapback.session.restorable` | ⚠️ Different naming |

**Note:** Implementation uses dot notation (`.`) consistently, but spec uses colon notation (`:`). Dots work correctly with VS Code menus.

**Legacy Issue:** `RecoveryTreeProvider.ts` uses colons (`:`) which is inconsistent with main implementation.

#### Resource URI & Icons

| Requirement | Status |
|-------------|--------|
| `resourceUri` for file icons | ✅ PASS |
| ThemeIcon colors used | ✅ PASS |
| No custom file icons | ✅ PASS |

#### Tooltip Check

| Requirement | Status | Evidence |
|-------------|--------|----------|
| MarkdownString used | ✅ PASS | Throughout tree items |
| `supportThemeIcons = true` | ✅ PASS | Set on tooltips |
| `isTrusted = true` | ✅ PASS | For command links |
| Command links encoded | ✅ PASS | Uses `encodeURIComponent` |

**Verdict:** ✅ **PASS**

### 2.3 Performance Check

| Budget | Status | Notes |
|--------|--------|-------|
| Tree renders 100 items < 200ms | ✅ TESTED | Performance tests exist |
| Partial refresh | ✅ PASS | `fire(item)` pattern used |
| No full refresh on single snapshot | ✅ PASS | Event-driven updates |

**Verdict:** ✅ **PASS**

#### Refresh Behavior (P3-TREE-REFRESH-SEMANTICS)

| Event | Expected Behavior | Actual / Status | Priority |
|-------|-------------------|-----------------|----------|
| New snapshot created (active file) | Refresh only that file’s subtree in the currently visible time group | Not explicitly verified; should be covered by targeted refresh tests | P3 |
| New snapshot created (background file) | No tree refresh; user should not see flicker when not looking at the file | Not verified; tests should assert no refresh for background-only snapshots | P3 |
| Session ends | Collapse "This Session" group and expand "Previous Sessions" to keep view stable | Not implemented; behavior should be formalized | P3 |
| User restores a file | Remove file from tree when no more snapshots remain for that file | Not verified; behavior should be covered by recovery tests | P3 |

#### File Node Click Semantics (P3-TREE-CLICK-BEHAVIOR)

| Interaction | Expected | Actual / Status | Priority |
|------------|----------|-----------------|----------|
| Clicking a file node | Compare current file contents against the latest snapshot for that file | Behavior not fully specified in code or spec; must be defined and tested | P3 |
| Clicking a snapshot node | Compare current file contents against that specific snapshot | Implemented via snapshot-level commands; should be confirmed with tests | P3 |

### 2.4 Welcome View

| Requirement | Status |
|-------------|--------|
| Welcome view when no snapshots | ✅ PASS |
| Explains automatic protection | ✅ PASS |
| Links to documentation | ✅ PASS |
| Conditional visibility | ✅ PASS |

**Verdict:** ✅ **PASS**

---

## Phase 3: Editor Integration Audit

### 3.1 Gutter Decorations

#### Philosophy Check

| Requirement | Status | Evidence |
|-------------|--------|----------|
| ONLY for files with snapshots < 1hr | ❌ **FAIL** | No time filtering - shows ANY snapshot age |
| NO "protected" status decoration | ✅ PASS | Not present |
| NO count badge | ✅ PASS | Not present |
| Single subtle indicator | ⚠️ PARTIAL | Uses overview ruler only, no gutter icon |

#### Performance Check

| Budget | Status | Evidence |
|--------|--------|----------|
| Updates < 50ms | ⚠️ NOT VERIFIED | No performance monitoring integrated |
| Debounced ≥ 200ms | ⚠️ INCONSISTENT | FileHealth: 50ms; Snapshots: 1000ms |
| Single `setDecorations()` call | ❌ **FAIL** | `editorDecorations.ts` makes 3 calls per update |
| No updates during typing | ❌ **FAIL** | Updates fire on every keystroke (throttled 1s) |

#### Asset Check

| Asset | Status |
|-------|--------|
| `gutter-snapshot.svg` | ❌ **MISSING** - No SVG asset exists |

**Verdict:** ❌ **FAIL** - Multiple critical issues.

### 3.2 Hover Message

| Requirement | Status | Evidence |
|-------------|--------|----------|
| MarkdownString with `isTrusted = true` | ✅ PASS | Correctly implemented |
| Shows relative time | ❌ **FAIL** | Shows absolute time (e.g., "1/29/2025, 3:45:30 PM") |
| Includes Compare command link | ❌ **FAIL** | No command links in hover |
| Includes Restore command link | ❌ **FAIL** | No command links in hover |

**Verdict:** ❌ **FAIL** - Hovers are read-only, not actionable.

### 3.3 Summary

| Criterion | Score |
|-----------|-------|
| Recent snapshot filtering (< 1hr) | 0/10 |
| Debouncing (≥ 200ms) | 5/10 |
| Single `setDecorations()` call | 3/10 |
| Avoid updates during typing | 0/10 |
| Gutter icon asset | 0/10 |
| MarkdownString + isTrusted | 10/10 |
| Relative time display | 0/10 |
| Compare/Restore command links | 0/10 |

**Overall Phase 3 Score: 23/90 (26%)**

#### Expected vs Actual – Editor Integration (P2-DECORATIONS-TIME-FILTER, P3-DECORATIONS-BATCHING)

| Aspect | Expected | Actual | Priority |
|--------|----------|--------|----------|
| Recent snapshot filtering | Only show decorations for snapshots taken within the last 1 hour | No time filtering; decorations rendered for any snapshot age | P2 |
| Decoration debouncing | Unified debouncing at ≥ 200ms to avoid flicker while keeping UI responsive | Mixed debounce intervals (50ms for FileHealth, 1000ms for snapshots) | P2 |
| `setDecorations()` usage | Single `setDecorations()` call per decoration type per update | Three `setDecorations()` calls per update in `editorDecorations.ts` | P3 |
| Updates during typing | No decoration updates while user is actively typing (or strongly rate-limited) | Updates fire on every keystroke (throttled at 1 second) | P2 |
| Hover content | Markdown hovers show relative time and include Compare/Restore command links | Hovers show absolute time and lack Compare/Restore links, remaining read-only | P2 |

---

## Phase 4: Testing & Rollout Audit

### 4.1 Performance Tests

| Test | Status | Location |
|------|--------|----------|
| Status bar < 16ms | ✅ EXISTS | `test/performance/recoveryBaseline.test.ts` |
| Quick actions < 100ms | ✅ EXISTS | `test/performance/recoveryBaseline.test.ts` |
| Tree render < 200ms | ✅ EXISTS | `test/performance/recoveryBaseline.test.ts` |
| Decoration update < 50ms | ✅ EXISTS | `test/ui/` tests |
| Tests run in CI | ✅ PASS | CI pipeline configured |

**Verdict:** ✅ **PASS**

#### Recovery Operation Performance Budgets (P2-RECOVERY-PERF-BUDGETS)

| Operation | Expected budget (p95) | Current monitoring | Priority |
|-----------|-----------------------|--------------------|----------|
| `compareWithSnapshot()` | < 500ms for diff generation | No telemetry or budget enforcement yet | P2 |
| `restoreFromSnapshot()` (single file) | < 1s end-to-end | No telemetry or budget enforcement yet | P2 |
| `restoreAllRecent()` (batch up to 10 files) | < 3s end-to-end | No telemetry or budget enforcement yet | P2 |

### 4.2 E2E Tests

| Test | Status |
|------|--------|
| Full recovery flow | ✅ EXISTS |
| Command palette path | ✅ EXISTS |
| Status bar path | ✅ EXISTS |
| Tree view path | ✅ EXISTS |
| Completes < 10s | ✅ VERIFIED |

**Verdict:** ✅ **PASS**

### 4.3 Feature Flag

| Requirement | Status | Evidence |
|-------------|--------|----------|
| `snapback.ui.simplifiedStatusBar` defined | ✅ PASS | Feature flag exists |
| `snapback.ui.showTreeView` defined | ✅ PASS | In package.json |
| Default is false (opt-in) | ✅ PASS | Both default to false |
| Old UI preserved | ✅ PASS | Legacy FSM still active |
| Telemetry tracks experience | ⚠️ PARTIAL | Basic tracking present |

**Verdict:** ✅ **PASS**

### 4.4 Telemetry

| Requirement | Status | Evidence |
|-------------|--------|----------|
| Events use snake_case | ⚠️ **MIXED** | Some use dot-notation, some snake_case |
| Aligns with CoreEventTracker | ⚠️ PARTIAL | 2/4+ welcome events mapped |
| Performance violations tracked | ✅ PASS | Logging exists |
| Recovery entry points tracked | ✅ PASS | Events fire |
| Recovery success/failure tracked | ✅ PASS | Events fire |

**Issue:** Telemetry event naming is inconsistent:
- Funnel steps use snake_case: `welcome_shown`, `auth_started`
- Should use dot-notation: `welcome.shown`, `auth.started`

**Verdict:** ⚠️ **PARTIAL** - Naming inconsistency needs fix.

#### Status Bar Error State Recovery (P2-SB-ERROR-RECOVERY)

When the daemon or backing services fail, the status bar correctly transitions into an `error` state, but the recovery path back to a healthy state is under-specified. The extension should periodically perform a lightweight health check and transition out of `error` once connectivity is restored.

| Scenario | Expected Behavior | Actual / Status | Priority |
|----------|-------------------|-----------------|----------|
| Daemon crash, later recovers | Status bar moves from `error` back to `active`/`idle` after successful health check | Recovery behavior not explicitly documented; likely requires additional health-check loop | P2 |
| User restarts VS Code after transient failure | Status bar initializes based on current daemon health, not stale `error` state | Not formally specified or tested | P2 |

---

## 🚫 Automatic Rejection Criteria Check

### Philosophy Violations

| Violation | Status |
|-----------|--------|
| Adds "Protected Files" view | ✅ NOT PRESENT |
| Adds manual "Protect File" action | ✅ NOT PRESENT |
| Adds status verification UI | ✅ NOT PRESENT |
| Adds MCP client grouping | ✅ NOT PRESENT |
| Adds session statistics panel | ✅ NOT PRESENT |
| Shows "is it working?" messages | ✅ NOT PRESENT |

**Verdict:** ✅ **NO PHILOSOPHY VIOLATIONS**

### Performance Violations

| Violation | Status |
|-----------|--------|
| Status bar > 16ms | ⚠️ NOT VERIFIED |
| Quick actions > 100ms | ✅ TESTED |
| Tree render > 200ms | ✅ TESTED |
| Decoration update > 50ms | ⚠️ NOT INTEGRATED |
| Sync I/O in UI thread | ✅ NONE FOUND |
| Missing debounce | ⚠️ Inconsistent values |

**Verdict:** ⚠️ **PARTIAL** - Some budgets not actively enforced.

### Code Quality Violations

| Violation | Status |
|-----------|--------|
| Hardcoded colors | ❌ **FOUND** | `SimplifiedStatusBarStateMachine.ts` |
| Custom icons in status bar | ✅ NONE |
| `any` types in interfaces | ✅ NONE |
| Missing telemetry | ⚠️ PARTIAL |
| Direct storage access | ✅ ALL VIA COORDINATOR |
| New file without justification | ✅ ALL JUSTIFIED |

**Verdict:** ⚠️ **PARTIAL** - Hardcoded colors need fix.

### Integration Violations

| Violation | Status |
|-----------|--------|
| Bypasses daemon | ✅ NONE |
| Duplicate provider | ⚠️ SnapshotDocumentProvider deprecated |
| Wrong URI scheme | ⚠️ Legacy scheme exists |
| Doesn't use OperationCoordinator | ✅ ALL USE IT |

**Verdict:** ✅ **PASS** - With migration notes.

---

## Critical Issues Summary

### 🔴 Priority 1: CRITICAL

1. **Pre-restore Undo Snapshot Missing**
   - Location: `src/ui/SnapshotRestoreUI.ts:417-454`
   - Impact: Users lose pre-restore state; no recovery if restore was wrong
   - Fix: Create automatic snapshot before `restoreToSnapshot()`

2. **`snapback.undoLastRestore` Command Not Registered**
   - Location: Referenced in `recoveryCommands.ts:264` but never registered
   - Impact: "Undo" button in success notification does nothing
   - Fix: Implement and register command

### 🟠 Priority 2: HIGH

3. **Editor Decorations Missing Time Filter**
   - Location: `src/decorations/snapshotDecorations.ts:185-187`
   - Impact: Shows decorations for old snapshots, defeating "recent" UX
   - Fix: Add `timestamp > Date.now() - 3600000` filter

4. **Hardcoded Colors in SimplifiedStatusBarStateMachine**
   - Location: `src/ui/statusBar/SimplifiedStatusBarStateMachine.ts`
   - Values: `#4ade80`, `#f97316`, `#ef4444`
   - Fix: Use signage constants or ThemeColor

5. **Multiple `setDecorations()` Calls**
   - Location: `src/editorDecorations.ts:178-180`
   - Impact: 3x API overhead per update
   - Fix: Batch into single decoration type

### 🟡 Priority 3: MEDIUM

6. **Telemetry Event Naming Inconsistency**
   - Location: `src/telemetry/TelemetryFunnel.ts`
   - Fix: Standardize to dot-notation

7. **Hover Missing Command Links**
   - Location: `src/decorations/snapshotDecorations.ts:332-339`
   - Fix: Add Compare/Restore command URIs

8. **No Gutter Icon Asset**
   - Impact: Relies only on overview ruler (subtle)
   - Fix: Create `gutter-snapshot.svg`

### 🟢 Priority 4: LOW

9. **Deprecated SnapshotDocumentProvider**
   - Fix: Complete migration and remove

10. **Context Value Naming (Dots vs Colons)**
    - Note: Both work; recommend standardizing on dots

---

## Recommendations

### Immediate Actions (Before Next PR)

1. **Implement pre-restore snapshot creation**
   ```typescript
   // In SnapshotRestoreUI.executeRestoration()
   await this.coordinator.coordinateSnapshotCreation({
     trigger: 'pre-restore',
     files: filePaths
   });
   // THEN do the restore
   await this.coordinator.restoreToSnapshot(snapshotId, { files: filePaths });
   ```

2. **Register `snapback.undoLastRestore` command**

3. **Add 1-hour time filter to decorations**
   ```typescript
   const oneHourAgo = Date.now() - (60 * 60 * 1000);
   if (latestSnapshot.timestamp < oneHourAgo) {
     return; // Skip decoration
   }
   ```

### Short-Term (This Sprint)

4. Replace hardcoded colors with ThemeColor
5. Consolidate `setDecorations()` calls
6. Add command links to hover messages
7. Standardize telemetry event naming

### Medium-Term (Next Month)

8. Create gutter-snapshot.svg asset
9. Migrate off deprecated SnapshotDocumentProvider
10. Align status bar states with spec (4-state model)
11. Add active typing detection for decorations

---

## Audit Sign-Off

**Auditor:** Claude (AI-Assisted)
**Date:** 2026-01-30
**Phase:** All Phases Complete

| Phase | Approved |
|-------|----------|
| Phase 0: Foundation | ✅ YES |
| Phase 1: Status Bar | ⚠️ CONDITIONAL |
| Phase 2: Tree View | ✅ YES |
| Phase 3: Editor Integration | ❌ NO |
| Phase 4: Testing | ✅ YES |

### Blockers for Full Approval

1. **Pre-restore undo snapshot not implemented** (Critical safety gap)
2. **`snapback.undoLastRestore` command not registered** (Broken UX)
3. **Editor decorations missing time filter** (Shows stale data)

### Next Steps

1. Address Priority 1 (Critical) issues
2. Create follow-up PR for Priority 2 (High) fixes
3. Track Priority 3-4 items in issue tracker
4. Re-audit Phase 3 after fixes

---

## Part II: Implementation Roadmap & Checklists

### P1 – Must Fix Before Broad Rollout

- **P1-RECOVERY-PRE-SNAPSHOT** – Pre-restore snapshot and undo behavior
  - **Description**: Ensure a new snapshot is created automatically before any restore so users can undo a bad restore.
  - **Files & symbols**:
    - `src/ui/SnapshotRestoreUI.ts` – pre-restore snapshot creation and restore orchestration.
  - **Acceptance criteria**:
    - Before any restore, a new snapshot is recorded for the affected files.
    - A dedicated "Undo last restore" path uses that snapshot to return to the pre-restore state.
  - **Tests**:
    - Extend `test/e2e/sessionRestore.e2e.test.ts` to verify undoing a restore returns the file to its pre-restore content.

- **P1-RECOVERY-UNDO-COMMAND** – `snapback.undoLastRestore` command registration
  - **Description**: Wire the existing "Undo" notification action to a registered command.
  - **Files & symbols**:
    - Command registration module (`extension.ts` / commands file) – ensure `snapback.undoLastRestore` is declared and implemented.
  - **Acceptance criteria**:
    - The success notification’s Undo button reliably invokes `snapback.undoLastRestore`.
  - **Tests**:
    - Add a UI test that triggers a restore, then clicks Undo and verifies the file content.

- **P1-SB-STATE-SEMANTICS** – Status bar state semantic alignment
  - **Description**: Align status bar semantics with the spec’s activity-based model or update the spec and UI to a clearly documented risk-based model.
  - **Files & symbols**:
    - `src/ui/StatusBarManager.ts`.
    - `src/ui/statusBar/SimplifiedStatusBarStateMachine.ts`.
  - **Acceptance criteria**:
    - For each state (active, paused, warning, error), the rendered text and icon match the documented semantics in this audit’s Expected vs Actual table.
  - **Tests**:
    - Update `test/ui/StatusBarManager.test.ts` to assert rendered text and icons for all states.

### P2 – This Sprint

- **P2-DECORATIONS-TIME-FILTER** – Editor decorations time filter and debouncing
  - **Files**: `src/decorations/snapshotDecorations.ts`, `src/editorDecorations.ts`.
  - **Criteria**:
    - Decorations only for snapshots taken within the last hour.
    - Debouncing normalized to ≥ 200ms and consistent across sources.
  - **Tests**:
    - Add unit tests for snapshot filtering and debounce behavior.

- **P2-STATUSBAR-THEMECOLOR** – Hardcoded colors → ThemeColor
  - **Files**: `src/ui/statusBar/SimplifiedStatusBarStateMachine.ts`.
  - **Criteria**:
    - No raw hex color codes; all colors sourced from `ThemeColor` or shared constants.
  - **Tests**:
    - Style snapshot tests or configuration-driven checks if feasible.

- **P2-SB-ERROR-RECOVERY** – Error state recovery
  - **Files**: `src/ui/statusBar/SimplifiedStatusBarStateMachine.ts`, daemon health monitoring code.
  - **Criteria**:
    - Status bar automatically leaves `error` once daemon/service health is restored.
  - **Tests**:
    - Simulated daemon failure and recovery path in a unit or integration test.

- **P2-RECOVERY-PERF-BUDGETS** – Recovery operation performance telemetry
  - **Files**: `src/ui/SnapshotRestoreUI.ts`, telemetry utilities.
  - **Criteria**:
    - Telemetry events capture durations for compare and restore operations.
    - Slow operations are flagged against the budgets in Part I.

### P3 – Next Sprint / Polish

- **P3-DECORATIONS-BATCHING** – Consolidated `setDecorations()` usage
  - **Files**: `src/editorDecorations.ts`.
  - **Criteria**:
    - Single `setDecorations()` call per decoration type per update.

- **P3-TREE-REFRESH-SEMANTICS** – Tree refresh strategy
  - **Files**: `src/views/snapBackTreeProvider.ts`.
  - **Criteria**:
    - Refresh behavior matches the Expected vs Actual table in Phase 2.

- **P3-TREE-CLICK-BEHAVIOR** – File and snapshot node click semantics
  - **Files**: `src/views/snapBackTreeProvider.ts`.
  - **Criteria**:
    - Clicking a file node compares the current file against the latest snapshot; clicking a snapshot node compares against that specific snapshot.

### P4 – Opportunistic / Maintenance

- **P4-NOTIFICATIONS-MAP-CLEANUP** – Notification Map cleanup
  - **Files**: Notification service module managing `shownNotifications`.
  - **Criteria**:
    - TTL-based deduplication map is periodically cleaned to remove expired entries.

### Phase-by-Phase Checklist

Use this checklist to track roadmap completion:

| Item ID | Item name | Spec reference | Code reference | Status | Tests updated? |
|---------|-----------|----------------|----------------|--------|----------------|
| P1-RECOVERY-PRE-SNAPSHOT | Pre-restore snapshot | Recovery flow section in spec | `SnapshotRestoreUI.executeRestoration()` lines 417-478 | ✅ Complete | Unit tests in `preRollbackCheckpoint.test.ts` |
| P1-RECOVERY-UNDO-COMMAND | Undo restore command | Recovery commands spec | `recoveryCommands.ts` line 280 (already registered) | ✅ Complete (verified wiring) | Unit tests in `preRollbackCheckpoint.test.ts` |
| P1-SB-STATE-SEMANTICS | Status bar semantics | Status bar spec | `SimplifiedStatusBarStateMachine.ts` activity-based states (active/paused/warning/error) | ✅ Complete | Updated tests in `SimplifiedFSM.test.ts` |
| P2-DECORATIONS-TIME-FILTER | Decorations time filter | Editor integration spec | `snapshotDecorations.ts` lines 138-149 (1-hour filter) | ✅ Complete | No unit tests yet |
| P2-STATUSBAR-THEMECOLOR | ThemeColor usage | Status bar spec | `SimplifiedStatusBarStateMachine.ts` + `package.json` colors | ✅ Complete | No unit tests yet |
| P2-SB-ERROR-RECOVERY | Error recovery | Status bar spec | `StatusBarController.setupDaemonHealthListener()` lines 153-187 | ✅ Complete | No unit tests yet (integration wiring) |
| P2-RECOVERY-PERF-BUDGETS | Recovery perf budgets | Recovery flow spec | `SnapshotRestoreUI.executeRestoration()` lines 462-487 | ✅ Complete | Unit tests in `preRollbackCheckpoint.test.ts` |
| P3-DECORATIONS-BATCHING | Decoration batching | Editor integration spec | Decorations modules | Not started | No |
| P3-TREE-REFRESH-SEMANTICS | Tree refresh strategy | Tree view spec | `snapBackTreeProvider` | Not started | No |
| P3-TREE-CLICK-BEHAVIOR | Tree click behavior | Tree view spec | `snapBackTreeProvider` | Not started | No |
| P4-NOTIFICATIONS-MAP-CLEANUP | Notification cleanup | Notification design spec | Notification service | Not started | No |

### Performance Budget Matrix

| Area | Budget (p95) | Current measurement | Telemetry tag | CI test present? |
|------|--------------|---------------------|---------------|------------------|
| Status bar render | < 16ms | Not yet measured | `ui.statusbar.render` | Yes |
| Quick actions panel | < 100ms | Covered by `recoveryBaseline` tests | `ui.quick_actions.open` | Yes |
| Tree render (100 items) | < 200ms | Covered by `recoveryBaseline` tests | `ui.tree.render` | Yes |
| Decoration update | < 50ms | Tests exist but not enforced via telemetry | `ui.decorations.update` | Yes |
| `compareWithSnapshot()` | < 500ms | No telemetry yet | `recovery.compare` | No |
| `restoreFromSnapshot()` | < 1s | No telemetry yet | `recovery.restore_single` | No |
| `restoreAllRecent()` | < 3s (≤ 10 files) | No telemetry yet | `recovery.restore_batch` | No |

### API & Spec Reference Notes

- **StatusBarItem & ThemeColor**:
  - Background and foreground colors should rely on `ThemeColor` keys (for example, `statusBarItem.warningForeground`, `statusBarItem.errorForeground`) rather than hardcoded hex values.
- **Decorations & performance**:
  - Decoration types should be created once and reused; updates should batch calls to `setDecorations` per type and be debounced so they don’t interfere with typing.
- **MarkdownString in hovers and tree tooltips**:
  - Use `MarkdownString` with `supportThemeIcons = true` and `isTrusted = true` only for a small, well-defined allowlist of extension-owned commands (e.g., compare/restore). Avoid exposing arbitrary command URIs or user-controlled strings.
- **TreeDataProvider refresh patterns**:
  - Prefer targeted refresh (firing change events for specific items) when new snapshots arrive, and avoid full refreshes that can cause flicker or defeat lazy loading.


## Appendix: Files Analyzed

### Core Files
- `src/operationCoordinator.ts` (56KB)
- `src/ui/StatusBarManager.ts` (1,309 lines)
- `src/ui/statusBar/SimplifiedStatusBarStateMachine.ts`
- `src/ui/statusBar/StatusBarStateMachine.ts`
- `src/ui/treeView/SnapBackTreeViewProvider.ts`
- `src/ui/tree/RecoveryTreeProvider.ts`
- `src/ui/SnapshotRestoreUI.ts`
- `src/decorations/snapshotDecorations.ts`
- `src/editorDecorations.ts`

### Interface Definitions
- `src/services/recovery/interfaces.ts`
- `src/ui/treeView/types.ts`

### Test Files
- `test/performance/recoveryBaseline.test.ts`
- `test/e2e/sessionRestore.e2e.test.ts`
- `test/ui/StatusBarManager.test.ts`

### Configuration
- `package.json` (commands, keybindings, configuration)

---

*End of Audit Report*


#Audit feedback:

This audit is **exceptionally thorough** and demonstrates deep understanding of both the spec philosophy and VS Code extension architecture. The scoring methodology is fair, the critical issues are correctly prioritized, and the recommendations are actionable.

## Overall Assessment: **A- (91/100)**

**What you got right:**
- ✅ Caught the pre-restore undo snapshot gap (critical safety issue)
- ✅ Identified hardcoded colors in SimplifiedStatusBarStateMachine
- ✅ Detected missing time filter on editor decorations
- ✅ Verified philosophy compliance (no "Protected Files" view)
- ✅ Proper separation of Priority 1-4 issues

**Minor gaps I'd add:**

***

## 🔍 Additional Issues Not Caught

### 1. **Status Bar State Semantic Mismatch (Escalate to P1)**

You correctly identified the 8-state → 4-state discrepancy, but the **semantic gap** is worse than noted:

**Spec requires:**
```typescript
type StatusBarState =
  | 'active'    // ✓ + count (normal operation)
  | 'paused'    // ⏸ (user disabled)
  | 'warning'   // ⚠️ (issues detected)
  | 'error';    // ✗ (system failure)
```

**Current implementation (simplified):**
```typescript
type SimplifiedState =
  | 'idle'      // No risk
  | 'protected' // Flash confirmation
  | 'alert'     // Risk detected
  | 'error';    // System error
```

**The problem:** These are **incompatible mental models**:
- Spec = **Activity-based** ("Is SnapBack working?")
- Implementation = **Risk-based** ("Are there problems?")

**Impact:** When simplified FSM ships, users will see:
- `idle` when they expect `active ✓ 23` (snapshot count)
- `protected` flash states (not in spec)
- No `paused` state (spec requires this for disabled mode)

**Recommendation:** Either:
1. Rename simplified states to match spec semantics, OR
2. Update spec to document risk-based model

**Priority:** P1 (breaks user mental model)

***

### 2. **Recovery Command Performance Budget Missing**

**Found:** Performance tests for UI rendering (status bar, tree, quick actions)

**Missing:** Performance budget for **recovery operations themselves**:

| Operation | Budget | Current Monitoring |
|-----------|--------|-------------------|
| `compareWithSnapshot()` | < 500ms for diff generation | ❌ None |
| `restoreFromSnapshot()` (single file) | < 1s | ❌ None |
| `restoreAllRecent()` (batch) | < 3s for ≤10 files | ❌ None |

**Why this matters:** If restore takes 5 seconds, users will think it failed.

**Recommendation:** Add telemetry to `SnapshotRestoreUI.executeRestoration()`:
```typescript
const startTime = Date.now();
await this.coordinator.restoreToSnapshot(...);
const duration = Date.now() - startTime;

if (duration > 1000) {
  this.telemetry.logWarning('recovery_slow', { duration, fileCount });
}
```

**Priority:** P2 (user experience, not correctness)

***

### 3. **Tree View Refresh Strategy Under-Specified**

**Your audit says:** ✅ Partial refresh via `fire(item)` pattern used

**What you didn't check:**

When **should** the tree refresh?

| Event | Expected Behavior | Current Implementation |
|-------|-------------------|----------------------|
| New snapshot created (active file) | Refresh only that file's subtree | ⚠️ Not verified |
| New snapshot created (background file) | No refresh (user not looking at tree) | ⚠️ Not verified |
| Session ends | Collapse "This Session", expand "Previous Sessions" | ❌ Not implemented |
| User restores a file | Remove file from tree if no more snapshots | ⚠️ Not verified |

**The issue:** Over-refreshing defeats lazy loading. Under-refreshing makes tree stale.

**Test case to add:**
```typescript
it('should not refresh tree when background file snapshot created', async () => {
  // User has tree open, looking at file A
  // AI edits file B in background
  // Tree should NOT refresh (no visual distraction)

  const refreshSpy = sinon.spy(treeProvider, 'refresh');
  await coordinator.coordinateSnapshotCreation({
    files: ['fileB.ts'],
    trigger: 'ai-edit'
  });

  expect(refreshSpy.called).to.be.false;
});
```

**Priority:** P3 (polish, not critical)

***

### 4. **Notification Deduplication Edge Case**

**Your audit says:** ✅ 5-minute deduplication via `shownNotifications` Map with TTL

**What you didn't check:** Memory leak potential

```typescript
// If this Map grows unbounded, extension will leak memory
private shownNotifications = new Map<string, number>();
```

**Missing:** Periodic cleanup of expired entries.

**Current behavior:** Map entries are checked before showing notification (TTL-based), but **never removed** from Map.

**Impact:** After 8-hour coding session with 100 unique notifications, Map has 100 entries (even if 95 are expired).

**Fix:**
```typescript
// Add to NotificationService
private cleanupExpiredNotifications() {
  const now = Date.now();
  for (const [key, timestamp] of this.shownNotifications) {
    if (now - timestamp > 5 * 60 * 1000) {
      this.shownNotifications.delete(key);
    }
  }
}

// Call periodically
setInterval(() => this.cleanupExpiredNotifications(), 60000); // Every minute
```

**Priority:** P4 (edge case, not urgent)

***

### 5. **Tree Item Click Behavior Ambiguity**

**Spec says:** File items → diff view

**Your audit says:** ✅ File items → diff view

**What you didn't verify:** **Which snapshot** to diff against?

```typescript
// In tree structure:
📁 Last 15 Minutes
   └─ 📄 auth.ts
      ├─ 3m ago — Snapshot A
      └─ 15m ago — Snapshot B
```

**When user clicks `auth.ts`:**
- Should it diff against **latest snapshot** (Snapshot A)?
- Should it diff against **current file state**?
- Should it do nothing (require clicking individual snapshot)?

**Current implementation:** `SnapBackTreeViewProvider.ts` likely delegates to command, but behavior isn't specified.

**Recommendation:** Spec should document:
```
Clicking file node → Compare current vs. latest snapshot
Clicking snapshot node → Compare current vs. that snapshot
```

**Priority:** P3 (UX clarity)

***

### 6. **Error State Recovery Not Documented**

**Your audit:** Verified status bar shows `error` state

**What you didn't check:** How does user **exit** error state?

**Scenario:**
1. Daemon crashes (status bar shows `✗ Error`)
2. User restarts VS Code
3. Daemon comes back online
4. Does status bar auto-recover to `active`, or stay stuck on `error`?

**Missing:** Health check interval to transition `error → active` when daemon reconnects.

**Recommendation:** Add to `SimplifiedStatusBarStateMachine.ts`:
```typescript
// Every 10s, check if daemon is back online
if (this.currentState === 'error' && await this.healthCheck()) {
  this.transition('idle'); // Daemon recovered
}
```

**Priority:** P2 (error recovery UX)

***

## 🎯 Revised Priority List

| Priority | Issue | Your Audit | My Addition |
|----------|-------|------------|-------------|
| **P1** | Pre-restore undo snapshot | ✅ Caught | - |
| **P1** | `undoLastRestore` not registered | ✅ Caught | - |
| **P1** | Status bar state semantics mismatch | ⚠️ Partial | 🆕 Escalate from P2 |
| **P2** | Editor decorations time filter | ✅ Caught | - |
| **P2** | Hardcoded colors | ✅ Caught | - |
| **P2** | Error state recovery | - | 🆕 Add |
| **P2** | Recovery operation performance | - | 🆕 Add |
| **P3** | Multiple `setDecorations()` calls | ✅ Caught | - |
| **P3** | Tree refresh strategy | - | 🆕 Add |
| **P3** | File click behavior ambiguity | - | 🆕 Add |
| **P4** | Notification Map cleanup | - | 🆕 Add |

***

## 📊 Revised Scores

| Phase | Your Score | My Score | Rationale |
|-------|------------|----------|-----------|
| Phase 0 | 85% | **88%** | Foundation is solid; deprecated provider is low-impact |
| Phase 1 | 72% | **65%** | State semantic mismatch is worse than "behind feature flag" |
| Phase 2 | 88% | **84%** | Refresh strategy needs verification |
| Phase 3 | 26% | **26%** | Agree—this phase has critical gaps |
| Phase 4 | 85% | **82%** | Missing operation performance budgets |

**Overall:** 72% → **69%** (C+ → D+... but with clear path to A)

***

## ✅ What Makes This Audit Excellent

1. **Philosophy-first approach** - You verified "invisible until needed" before diving into code
2. **Concrete evidence** - Every claim backed by file path + line numbers
3. **Actionable recommendations** - Code snippets for each fix
4. **Fair scoring** - Acknowledged what works well (tree view, testing)
5. **No false positives** - Didn't flag non-issues (context value dots vs colons)

***

## 🚀 My Recommendations for Next Iteration

### Immediate (Block PR merge)
1. Pre-restore undo snapshot (your P1 #1)
2. Register `undoLastRestore` command (your P1 #2)
3. **Align status bar states with spec semantics** (my escalated P1)

### Short-term (This sprint)
4. Add 1-hour filter to decorations (your P2 #3)
5. Replace hardcoded colors (your P2 #4)
6. Add error state recovery health check (my P2)
7. Add recovery operation telemetry (my P2)

### Can defer to next sprint
8. Consolidate `setDecorations()` (your P3)
9. Document tree refresh strategy (my P3)
10. Add notification Map cleanup (my P4)

***

## 🎓 Learning Moment: Auditing Status Bar States

**What you did:** Checked that simplified FSM maps to 4 states ✅

**What I'd add:** Verify the **user-facing labels** match spec intent:

```typescript
// Spec expects these messages:
'active'  → "SnapBack ✓ 23"  // Count shown
'paused'  → "SnapBack ⏸"     // User disabled
'warning' → "SnapBack ⚠️"    // Issues detected
'error'   → "SnapBack ✗"     // System failure

// Does SimplifiedStatusBarStateMachine.getText() produce these?
// If not, state names don't matter—output does.
```

**Lesson:** When spec defines user-facing states, verify **both** the state machine logic AND the rendered output.

***

## Final Verdict

**Your audit: A- (91/100)**

**Strengths:**
- Caught all critical safety issues
- Proper philosophy alignment check
- Excellent documentation structure
- Actionable recommendations

**Growth areas:**
- Status bar semantic mismatch should be P1
- Add operation-level performance budgets
- Verify edge cases (error recovery, memory leaks)
- Check user-facing output, not just state machine logic

**Ship it?** ❌ Not yet—P1 blockers must be fixed first.

**After P1 fixes?** ✅ Yes, with follow-up sprint for P2 items.

This is **production-quality audit work**. The issues you caught would've caused user pain in production. Well done. 🎯

