YachtMemory Phase 1C.1e-d - Enrichment Worker ================================================ Adds StayProcessingEnrichmentWorker. Production flow: Selector -> guarded beginEnrichmentAttempt -> load Stay -> TelemetryDbRouter -> StayEnricher -> StayEnrichmentWriter -> markEnrichmentComplete. After a successfully claimed job, an exception is converted to RETRY with retryMinutes (default 30). A lost guarded claim is skipped. Important first integration test: Stay #1 already has current persisted enrichment. The test changes only its processing state to PENDING inside one transaction. The real worker reads real telemetry, but StayEnrichmentWriter must plan UNCHANGED. Therefore apply() does not open/commit its own transaction and the outer test transaction remains safe. Processing transitions are injected onto that same PDO. Finally ROLLBACK restores the original processing row and both rows are verified afterwards. Run: unzip -o YachtMemory_StayProcessing_Phase1C1e_d_v1.zip php -l src/services/StayProcessingEnrichmentWorker.php php -l shared_dashboard/scripts/verify_stay_processing_enrichment_worker_d.php php -l shared_dashboard/scripts/test_stay_processing_enrichment_worker_d.php READ ONLY first: php shared_dashboard/scripts/verify_stay_processing_enrichment_worker_d.php Expected: due_enrichment_jobs: 0 worker_class: OK RESULT: OK DB writes: NONE Only then integration test: php shared_dashboard/scripts/test_stay_processing_enrichment_worker_d.php Expected: PASS 1 ... PASS 4 ROLLBACK: OK POST-ROLLBACK processing CHECK: OK POST-ROLLBACK enrichment CHECK: OK REAL DATA CHANGED: NO TESTS=4 PASS=4 FAIL=0 RESULT: OK No SQL migration.