feat: QA engine — Vera spec MVP (4-week roadmap, Week 1-2 complete)#66
Merged
Conversation
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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)VideoMetadata.swiftVideoMetadata,QualityCheck,QASummary,QAChanges,QAReportFFProbeExtractor.swiftQAErrorenumQualityChecks.swiftQAAnalyzer.swiftanalyze(),analyzeAndSave(), JSON persistenceQAReport+Samples.swiftsamplePassed+sampleFailedfor Xcode Previews and testsQAIntegration.swiftrunAndNotify()background helper + integration pseudocodeSources/ScreenMuseApp/Views/QAReportView.swift(new)SwiftUI modal with:
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)
start_timePTS diff from ffprobe rather thanaresampletrick in spec — more accurate, no re-encode requiredisWarning=trueinstead ofpassed=false— spec says it's a warning, so UI surfaces it as amber, not redWhat's NOT Wired Yet (intentional)
The QA modal is not yet shown automatically because
VideoProcessorintegration requires a real macOS build environment to test. Integration code is inQAIntegration.swift:Acceptance Criteria (Vera's spec)