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.
