YachtMemory - Stay Processing Phase 1C.1e-b2
================================================
Purpose
-------
Introduce the production Enrichment worker-transition service, but DO NOT use
it against the real 36 Stay rows yet.

New file:
  src/services/StayProcessingTransitionService.php

New READ-ONLY verifier:
  shared_dashboard/scripts/verify_stay_processing_transitions_b2.php

No SQL migration.
StayProcessingWriter.php from validated b1 is not replaced.

Transition contract
-------------------
beginEnrichmentAttempt(stayId, inputRevision, at)
  PENDING or RETRY -> PROCESSING
  increments attempt_count
  writes last_attempt_at
  clears next_attempt_at and last_error

markEnrichmentComplete(stayId, inputRevision)
  PROCESSING -> COMPLETE
  clears next_attempt_at and last_error
  keeps attempt_count and last_attempt_at

markEnrichmentRetry(stayId, inputRevision, nextAttemptAt, error)
  PROCESSING -> RETRY
  sets next_attempt_at and last_error
  keeps attempt_count and last_attempt_at

markEnrichmentFailed(stayId, inputRevision, error)
  PROCESSING -> FAILED
  clears next_attempt_at
  sets last_error
  keeps attempt_count and last_attempt_at

Concurrency protection
----------------------
Every UPDATE includes:
  stay_id = expected stay
  enrichment_input_revision = worker's expected revision
  expected source status

If zero rows are affected, the transition is rejected. A worker for revision N
therefore cannot complete/retry/fail a row that has already moved to revision N+1.

Current package intentionally stops before controlled write testing.
We first install, lint and run the READ-ONLY baseline verifier.

Commands
--------
  unzip -o YachtMemory_StayProcessing_Phase1C1e_b2_v1.zip

  php -l src/services/StayProcessingTransitionService.php
  php -l shared_dashboard/scripts/verify_stay_processing_transitions_b2.php

  php shared_dashboard/scripts/verify_stay_processing_transitions_b2.php

Expected current baseline:
  rows_total: 36
  enrichment_not_complete: 0
  enrichment_attempt_nonzero: 0
  enrichment_last_set: 0
  enrichment_next_set: 0
  enrichment_error_set: 0
  input_revision_null: 0
  RESULT: OK
  DB writes: NONE

Next step after validation
--------------------------
Build an isolated transactional/synthetic write test. Do not mutate a real Stay
row merely to exercise the API.
