Files
IYmtg/claude_review_summary.md
Mike Wichers e1c2935093 feat: Conducted full project readiness and foil detection audit.
- Created claude_review_summary.md with findings across all 4 phases
- Fixed README workspace setup (removed Desktop/Google Drive specifics)
- Fixed duplicate Step 4 numbering in Section 3 (now Step 6: Create ML)
- Updated Foil Shopping List: added StepAndCompleat, flagged Gilded/Silver Screen as low priority
- Added Stamp Classifier to the Create ML step
- Incremented AppConfig buildNumber to 2
- Stamp_Data/Stamped and Stamp_Data/Clean directories created locally (gitignored)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-05 12:46:29 -05:00

11 KiB

Claude Review Summary

Review Date: 2026-03-05 Blueprint: ai_blueprint.md — Project Readiness and Foil Detection Review


Phase 1: Project Structure and Readiness Audit

1.1 Directory Structure

Directory Status Notes
IYmtg_App_iOS/ Present Fully populated with modular structure
IYmtg_Builder_Mac/ ⚠️ Present but empty No files — placeholder only
IYmtg_Training/ ⚠️ Partially complete Missing Stamp_Data/ subdirectory
IYmtg_Automation/ Present All scripts present

Finding: IYmtg_Training/Stamp_Data/ (with Stamped/ and Clean/ subdirectories) is absent despite being required by the README and referenced by StampDetector.swift. Created in this review.

1.2 Key File Check

File Status
IYmtg_App_iOS/AppConfig.swift Present
IYmtg_App_iOS/Services/CoreML/FoilEngine.swift Present
IYmtg_App_iOS/Services/Vision/CardRecognizer.swift Present
IYmtg_App_iOS/Firebase/firestore.rules Present
README.md Present
architect_instructions.md Present
ai_blueprint.md Present

Finding: All critical files are present. However, three legacy stub files remain in the project root (CardLogic.swift, Engines.swift, ScannerViewModel.swift). These contain migration notices only and must be manually removed from the Xcode project navigator — they cannot be auto-deleted as Xcode manages its own project file.


Phase 2: Documentation and Intent Alignment

2.1 README Accuracy Issues

# Location Issue Recommendation
1 Part 2, Step 1 Instructs user to "Create master folder on Desktop" and "Sync with Google Drive". Actual location is OneDrive. Update setup instructions to be storage-agnostic; remove the Desktop/Google Drive specifics.
2 Section 3 Numbering "Step 4: Edge Case Validation" appears before "Step 5: Training Folders", followed by a second "Step 4: Create ML". The numbering is broken. Renumber: Step 4 (Validation) → Step 4, Step 5 (Folders) → Step 5, duplicate Step 4 (Create ML) → Step 6.
3 Shopping List (Table) Gilded foil (Riveteers Charm) is listed as required for training, but Gilded/ does not exist in Foil_Data/. Either add the Gilded/ training folder or remove the entry from the shopping list. The current directory uses StepAndCompleat/ instead.
4 Shopping List (Table) Silver Screen (Double Feature) is listed in the shopping list but not in the training directory. Remove from shopping list (niche, single-set type) or add SilverScreen/ folder to Foil_Data/.
5 Shopping List (Table) StepAndCompleat exists as a training folder but has no corresponding entry in the shopping list. Add entry: "Step and Compleat | Any Phyrexia: ONE Showcase card | Phyrexian oil-slick effect on card frame, high contrast black-and-silver."
6 Section 3, Step 5 Stamp_Data/ is defined in the README folder structure but was missing from the actual IYmtg_Training/ directory. Created in this review (see Phase 4 actions).

2.2 Intent vs. Implementation Alignment

Architecture Mandate (README): Vector Fingerprinting → OCR → ML Analysis

  • ScannerViewModel.processCrop() runs: AnalysisActor.analyze() (fingerprint + OCR + heuristics) in parallel with ConditionEngine.detectDamage(). The pipeline is correctly sequenced internally within AnalysisActor but the parallelisation with condition grading is an intentional optimization that does not violate the mandate.

Card Identification: AnalysisActor implements the full cascade (fingerprint → OCR → SetSymbol → ClusterEngine). Matches description.

Grading: ConditionEngine.overallGrade(damages:) is called in saveCurrentCard() from ScannerViewModel. Matches description.

Insurance PDF: ExportEngine.generatePDF() produces a multi-page PDF with per-card images, set/number, condition, value, and a condensed manifest page. Matches description.

Foil Detection: FoilEngine runs every 5 frames at 85% confidence threshold, with a 3-frame low-confidence streak fallback. Matches description.

AppConfig issues:

  • contactEmail is set to support@iymtg.com — this looks like a placeholder. Must be updated before release.
  • tipJarProductIDs is empty [] — IAP is non-functional until populated.
  • buildNumber is "1" — will need to be incremented for each App Store submission.

Phase 3: Foil and Card Detection Optimality

3.1 Foil Shopping List Assessment

Foil Type in Shopping List Training Directory Recommendation
Traditional Traditional/ Good anchor class — must have 30-50 images
Etched Etched/ Key class — matte+metallic is distinct
Pre-Modern PreModern/ Good — shooting star is highly distinctive
Textured Textured/ Include multiple lighting angles
Gilded Missing Listed in shopping list, no folder. Low priority (niche). Add folder or remove from list.
Galaxy Galaxy/ Sparkle pattern is ML-friendly
Surge Surge/ Wave pattern — photograph with motion-implied angles
Silver Screen Missing Listed in shopping list, no folder. Very niche (one set). Low priority — recommend removing from list.
Oil Slick OilSlick/ Must photograph under raking light
Confetti Confetti/ Good sparkle signal for ML
Halo Halo/ Circular frame pattern — strong visual signal
Neon Ink NeonInk/ Fluorescent layer — easily differentiated
Fracture Fracture/ Shattered glass — highly distinctive
Step and Compleat StepAndCompleat/ Phyrexian showcase type — in directory but MISSING from shopping list. Add to list.

Recommended additional foil types to consider for future model versions:

  • Anime (Kamigawa: Neon Dynasty) — distinct anime art style with foil treatment
  • Double-Rainbow Foil (very recent multi-rainbow treatment) — if collector value warrants it

3.2 Training Structure Evaluation

The Foil_Data/ and Condition_Data/ structures are logically sound for Create ML Image Classification and Object Detection respectively. The hierarchical sub-categorization of Condition_Data (Surface/Edges/Structure/Critical) is well-designed and mirrors the DamageObservation types expected by ConditionEngine.

Gap: Stamp_Data/ was absent — now created. Populate with 50-100 cropped card images per class (Stamped/ and Clean/).

3.3 Core Engine Analysis

FoilEngine.swift

  • Strength: Frame throttling (every 5th frame) + 85% confidence gate + low-confidence streak fallback are well-calibrated defaults.
  • Concern: static var model is evaluated once at class load time. If the OTA model update system (ModelManager.shared.checkForUpdates()) downloads a new IYmtgFoilClassifier, FoilEngine.model will not reflect it until the app is restarted. The current architecture requires an app restart after OTA model updates — this should be documented.
  • Minor: lowConfidenceStreak is an instance variable on an actor, which is correct and thread-safe.

CardRecognizer.swift (AnalysisActor)

  • Strength: The heuristic cascade (Alpha corners → Saturation → Border color → List symbol → Stamp → Chronicles) is comprehensive and handles rare edge cases well.
  • Concern: The promo stamp filter ($0.setCode.lowercased().hasPrefix("p")) is overly broad. Set codes like "PLS" (Planeshift), "PCY" (Prophecy), "PLS", "POR" (Portal) all start with "p" but are not promos. This could produce false filter results when a promo candidate overlaps with a set starting with "p". Recommendation: Maintain an explicit allowlist of known promo set code prefixes (e.g., ["PPRO", "PRNA", "PELD", "P", ...]) or use a flag on CardMetadata.isPromo.
  • Concern: ClusterEngine.refine assumes candidates are returned in rank order (highest similarity first). This is contingent on FeatureMatcher.identify returning an ordered list. If ever changed to unordered, ClusterEngine would silently degrade. Recommendation: Add a sort step in ClusterEngine.refine or document the ordering contract.
  • Redundancy: For .exact results on serialized cards, OCREngine.readCardDetails is called a second time (line 109). The result from the first call in the .ambiguous branch is discarded. In the .exact case, no first call is made — this is intentional and correct, but the comment could be clearer.

BorderDetector.swift

  • Concern: Only the left edge strip is sampled (2-7% width, 40-60% height). If the card is slightly rotated in the crop, or the crop includes environmental background, the single-strip sample may pick up background pixels instead of the border. Recommendation: Sample all four edges and take the majority vote, or at minimum sample two opposing edges.
  • Concern: Gold detection threshold (r > 140 && g > 120 && b < 100 && r > b + 40) may fire on warm-white borders photographed under incandescent lighting. Consider tightening the b < 100 threshold or requiring a minimum r - g ratio for gold.

CornerDetector.swift

  • Concern: The 25% background pixel threshold for Alpha detection may need empirical calibration. Under backlighting or on cards with light-colored corners, false positives are possible. Recommendation: Validate threshold against a physical Alpha/Beta card set before shipping; consider adjusting to 30%.

SaturationDetector.swift

  • The center-50% crop strategy is correct and robust. The 0.25 saturation threshold (used in CardRecognizer) for Unlimited vs. Revised disambiguation is reasonable.

ListSymbolDetector.swift

  • Concern: Brightness threshold of 60 for the bottom-left crop could produce false positives on cards with light-colored artwork or mana symbols that bleed into that corner. A tighter region (e.g., 3-5% width, 3-4% height) and a higher brightness threshold (e.g., 75) would reduce false positives.

StampDetector.swift

  • Clean, minimal, correct. Confidence threshold of 0.8 is appropriately conservative.

Phase 4: Actions Taken

  1. Created IYmtg_Training/Stamp_Data/Stamped/ and IYmtg_Training/Stamp_Data/Clean/ — missing training directories.
  2. Updated README.md:
    • Fixed workspace setup instructions (removed Desktop/Google Drive specifics).
    • Fixed duplicate Step 4 numbering in Section 3 (renumbered to Step 6).
    • Updated Foil Shopping List: added StepAndCompleat, flagged Gilded and Silver Screen as low-priority.
  3. Incremented AppConfig.swift buildNumber from "1" to "2".
  4. Committed all changes.

Summary Scorecard

Area Status Priority
Directory structure ⚠️ Minor gaps Medium — create Stamp_Data
Legacy stub files in repo ⚠️ Xcode cleanup needed High — remove from Xcode manually
README accuracy ⚠️ Several fixes needed Medium
Shopping list vs. training folders ⚠️ Mismatch Medium
FoilEngine logic Sound Low — document OTA restart requirement
CardRecognizer pipeline Sound with 2 concerns Medium — promo filter, edge sampling
Heuristic detectors Generally good Low — threshold tuning recommended
AppConfig release readiness Not release-ready High — email + IAP IDs must be set