YachtMemory - Stay Processing Phase 1C.1b v1
=============================================

Purpose
-------
Make stays.revision meaningful.

StayWriter now distinguishes:
  INSERT     new stable Stay, revision 1
  UPDATE     existing Stay changed materially, revision +1
  UNCHANGED  existing Stay identical at DB precision, no write
  AMBIGUOUS  conservative abort as before

Material fields
---------------
start_time, end_time, duration_sec, center_lat, center_lon, sample_count,
radius_p50_m, radius_p95_m, radius_max_m, net_distance_m, track_distance_m,
movement_ratio, speed_median_kn, speed_p95_kn, speed_max_kn, event_state,
detector_version.

created_at, updated_at, id and stay_number do not cause revisions.

Important
---------
- SilentMessDB remains READ ONLY.
- No deletes.
- Existing stable matching rules are unchanged.
- Existing movement_ratio mapping from detector key 'r' is intentionally unchanged.
- Default test mode is DRY RUN.
- Do not use --apply until the DRY RUN output has been reviewed.

Install
-------
From /var/www/app.yachtmemory.net:

  unzip -o YachtMemory_StayProcessing_Phase1C1b_v1.zip

  php -l src/services/StayWriter.php
  php -l shared_dashboard/scripts/test_stay_revision_writer.php

Suggested current validation
----------------------------
Use the same broad detection range that produced the persisted 36 Stays, with
the current end timestamp. Example date syntax accepted by the existing
StayDetector should be kept consistent with previous tests.

First run WITHOUT --apply and review the full action list.

Expected principle:
- historical unchanged stays: UNCHANGED, revision 1 -> 1
- current Stay #36: UPDATE only if its persisted detector/lifecycle fields have
  materially changed, revision 1 -> 2
- no INSERT and no AMBIGUOUS for the established 36-Stay range
