Skip to content

feat: QA engine — Vera spec MVP (4-week roadmap, Week 1-2 complete)#66

Merged
hnshah merged 2 commits into
mainfrom
feat/qa-engine-vera-spec
Apr 4, 2026
Merged

feat: QA engine — Vera spec MVP (4-week roadmap, Week 1-2 complete)#66
hnshah merged 2 commits into
mainfrom
feat/qa-engine-vera-spec

Conversation

@hnshah
Copy link
Copy Markdown
Owner

@hnshah hnshah commented Apr 4, 2026

What This Does

Implements the QA engine from Vera's spec (2026-04-03). After video processing, users see a modal with quality checks + before/after metrics.

Files Added (8 files, 1,636 lines)

Sources/ScreenMuseCore/QA/ (new module)

File What
VideoMetadata.swift Codable model types: VideoMetadata, QualityCheck, QASummary, QAChanges, QAReport
FFProbeExtractor.swift ffprobe-based metadata extraction, QAError enum
QualityChecks.swift All 5 checks: file validity, resolution, A/V sync, frame rate, file size
QAAnalyzer.swift Orchestrator: analyze(), analyzeAndSave(), JSON persistence
QAReport+Samples.swift samplePassed + sampleFailed for Xcode Previews and tests
QAIntegration.swift runAndNotify() background helper + integration pseudocode

Sources/ScreenMuseApp/Views/QAReportView.swift (new)

SwiftUI modal with:

  • Header: status icon + confidence % badge
  • Quality checks list (✅/❌/⚠️ per check)
  • Before/after metrics Grid (duration, file size, bitrate, resolution, fps)
  • Footer: Show in Finder · Export Report (NSSavePanel) · Done (Esc)
  • Both light/dark mode friendly

Tests/ScreenMuseCoreTests/QAAnalyzerTests.swift (new)

25 test cases covering rational FPS parsing, all 5 quality checks, confidence score math, JSON round-trip, report path derivation.

Spec Deviations (improvements)

  • A/V sync: Uses start_time PTS diff from ffprobe rather than aresample trick in spec — more accurate, no re-encode required
  • File size warning: isWarning=true instead of passed=false — spec says it's a warning, so UI surfaces it as amber, not red
  • Confidence score: Weighted by severity (critical=-0.40, high=-0.25, medium=-0.15, low=-0.05) vs simple pass/fail ratio

What's NOT Wired Yet (intentional)

The QA modal is not yet shown automatically because VideoProcessor integration requires a real macOS build environment to test. Integration code is in QAIntegration.swift:

// Add to VideoProcessor after processedURL is written:
Task.detached(priority: .utility) {
    QAIntegration.runAndNotify(original: originalURL, processed: processedURL)
}

// Add to ContentView/AppDelegate:
.onReceive(NotificationCenter.default.publisher(for: .showQAReport)) { notification in
    // present QAReportView as sheet
}

Acceptance Criteria (Vera's spec)

  • QA report model matches JSON schema exactly
  • All 5 quality checks implemented
  • Before/after metrics (duration, file size, bitrate)
  • Export Report button (NSSavePanel → JSON)
  • Show in Finder button
  • Done button (Esc shortcut)
  • Error state shown when checks fail
  • No external dependencies (ffprobe already bundled)
  • Auto-show after processing (needs VideoProcessor wiring in app)
  • QA < 5s performance test (needs macOS hardware)

Oatis added 2 commits April 4, 2026 07:40
Implements the full ScreenMuse QA feature per Vera's spec (2026-04-03).

## What's added

### Sources/ScreenMuseCore/QA/ (new module)
- VideoMetadata.swift — Codable structs: VideoMetadata, QualityCheck,
  QASummary, QAChanges, QAReport, QAVideos
- FFProbeExtractor.swift — ffprobe-based metadata extraction + QAError enum
- QualityChecks.swift — all 5 checks: file validity, resolution, A/V sync,
  frame rate, file size (warning-only for >2x)
- QAAnalyzer.swift — orchestrator: analyze() + analyzeAndSave() + persistence
- QAReport+Samples.swift — samplePassed + sampleFailed for previews/tests
- QAIntegration.swift — background Task helper + integration docs/pseudocode

### Sources/ScreenMuseApp/Views/QAReportView.swift (new)
- SwiftUI modal: header (status + confidence %), checks list, before/after
  metrics grid, footer buttons (Show in Finder, Export Report, Done)
- NSSavePanel export → .qa-report.json
- NotificationCenter.showQAReport for cross-module triggering
- Previews for both passed and failed states

### Tests/ScreenMuseCoreTests/QAAnalyzerTests.swift (new)
- 25 test cases covering: rational FPS parsing, all 5 quality checks,
  confidence score computation, JSON round-trip, report path derivation,
  VideoMetadata computed properties, QAChanges math

## Deviations from spec (improvements)
- A/V sync: uses PTS start_time diff via ffprobe (more accurate than
  aresample trick suggested in spec)
- File size >2x: marked as isWarning=true (not a hard failure) — spec says
  it's a warning, so we surface it that way in UI
- Confidence score: weighted by severity rather than simple pass/fail ratio

## Integration (not yet wired — see QAIntegration.swift)
After video processing completes in VideoProcessor, add:
  Task.detached { QAIntegration.runAndNotify(original:, processed:) }
And observe NotificationCenter.showQAReport to present QAReportView as sheet.
- RecordViewModel: after effects compositing succeeds, spawn a background
  Task that calls QAIntegration.analyze() and stores the report in
  @published pendingQAReport / pendingQAProcessedURL
- RecordView: .sheet() binding on pendingQAReport → shows QAReportView
  automatically when report arrives; dismissing clears the state
- No-effects path: QA not applicable (original === output), no change there

Full end-to-end flow: Record → Apply Effects → QA runs in background →
Modal appears automatically with quality checks + before/after metrics.
@hnshah hnshah merged commit 141ff03 into main Apr 4, 2026
1 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant