|
| 1 | +# Storebaelt Phase 1 Freshness-First Execution Plan |
| 2 | + |
| 3 | +**Date:** 2026-06-03 |
| 4 | +**Scope:** Recommended next implementation step for the Storebaelt webcam publisher and Explorer UI. |
| 5 | +**Decision:** Do the poster/freshness hardening first, and keep it separate from the later on-demand live/HLS webcam enhancement. |
| 6 | + |
| 7 | +## Related Documents |
| 8 | + |
| 9 | +- `Storebaelt_Webcam_Poster_Integration_Status_and_UX_Options_2026-06-03.md` explains the current poster-image integration, why unchanged images can appear stale, and the UX options for freshness/status reporting. |
| 10 | +- `Storebaelt_On_Demand_Live_Webcam_Enhancement_Plan_2026-06-03.md` describes the later lease-based live/HLS enhancement that activates only when a client requests it and shuts down when not in use. |
| 11 | +- `Publisher_Thumbnail_Remediation_Plan_2026-05-29.md` provides broader context for image/thumbnail handling in the publisher fleet. |
| 12 | +- `Oracle_New_Publisher_Service_Sanity_Check_2026-05-26.md` provides deployment sanity-check context for new Oracle publisher services. |
| 13 | + |
| 14 | +## Recommendation |
| 15 | + |
| 16 | +Proceed with the Phase 1 poster/freshness updates now, as a contained production hardening pass. Treat the improved live/HLS webcam experience as Phase 2, beginning only after the baseline poster-source UX is truthful and useful. |
| 17 | + |
| 18 | +Phase 1 fixes the problem currently visible in Explorer regardless of whether the HLS path later proves easy, fragile, tokenized, CORS-blocked, or CPU-heavy. It makes the current integration honest: users can see when the publisher last checked the source, when the image content last changed, and whether the camera source appears stale. |
| 19 | + |
| 20 | +## Why Keep Phase 1 Separate from Live/HLS |
| 21 | + |
| 22 | +### 1. The data semantics are different |
| 23 | + |
| 24 | +Poster freshness is a durable baseline observation stream. Live/HLS mode is a transient, user-triggered enhancement. Mixing them too early risks muddying what observation timestamps mean. |
| 25 | + |
| 26 | +Phase 1 should make these concepts explicit: |
| 27 | + |
| 28 | +- poll/check time |
| 29 | +- image content change time |
| 30 | +- unchanged duration |
| 31 | +- stale/unavailable status |
| 32 | + |
| 33 | +Live/HLS can later add separate live activation state, frame time, lease state, and source latency. |
| 34 | + |
| 35 | +### 2. The operational profile is different |
| 36 | + |
| 37 | +Poster polling is cheap, predictable, and always-on. Live/HLS capture is heavier and should be demand-driven. Keeping them separate preserves a boring, reliable baseline publisher while allowing the later live worker to be bounded by leases, TTLs, rate limits, and idle shutdown. |
| 38 | + |
| 39 | +### 3. The UI needs Phase 1 concepts either way |
| 40 | + |
| 41 | +Even if live/HLS works well, Explorer still needs to explain poster freshness, fallback state, last check time, and stale status whenever live mode is off or unavailable. Phase 1 builds the UI vocabulary that the live enhancement will reuse. |
| 42 | + |
| 43 | +## Phase 1 Implementation Tasks |
| 44 | + |
| 45 | +### Publisher tasks |
| 46 | + |
| 47 | +1. Change the Storebaelt publisher to publish heartbeat/status observations every 5 minutes, even when the poster image hash has not changed. |
| 48 | +2. Preserve image content dedupe metadata, but do not suppress the heartbeat observation. |
| 49 | +3. Add result fields such as: |
| 50 | + - `imageChanged` |
| 51 | + - `firstSeenTime` |
| 52 | + - `lastSeenTime` |
| 53 | + - `lastChangedTime` |
| 54 | + - `unchangedPollCount` |
| 55 | + - `stalenessStatus` |
| 56 | + - `sourceAgeSeconds` |
| 57 | +4. Keep `imageSha256`, `imageUrl`, `posterUrl`, `playerUrl`, and `pageUrl` in the result payload. |
| 58 | +5. Update the Storebaelt datastream schema to include the new fields. |
| 59 | +6. Add focused tests for changed-image and unchanged-image cycles. |
| 60 | +7. Verify local dry-run behavior against the public Storebaelt poster URLs. |
| 61 | + |
| 62 | +### Explorer tasks |
| 63 | + |
| 64 | +1. Update the deployed-system card logic for webcam/image datastreams. |
| 65 | +2. Display: |
| 66 | + - latest image |
| 67 | + - last checked |
| 68 | + - image changed |
| 69 | + - unchanged duration |
| 70 | + - stale badge |
| 71 | + - public page link |
| 72 | + - embedded player link |
| 73 | +3. Make the card distinguish between: |
| 74 | + - publisher alive but image unchanged |
| 75 | + - source stale |
| 76 | + - source unavailable |
| 77 | + - no observation yet |
| 78 | +4. Keep the poster image visible when live mode is unavailable or not yet implemented. |
| 79 | + |
| 80 | +### Deployment tasks |
| 81 | + |
| 82 | +1. Deploy the publisher changes to Oracle. |
| 83 | +2. Re-run or update bootstrap if schema changes require it. |
| 84 | +3. Restart `storebaelt-webcams-publisher.service`. |
| 85 | +4. Confirm service logs show heartbeat observations with zero errors. |
| 86 | +5. Confirm Explorer displays the updated freshness state. |
| 87 | + |
| 88 | +## Phase 1 Acceptance Criteria |
| 89 | + |
| 90 | +- Storebaelt observations continue to arrive every 5 minutes even if the poster image bytes do not change. |
| 91 | +- Observation payloads clearly identify whether image content changed. |
| 92 | +- Explorer does not make a 20+ minute unchanged image look like a dead publisher. |
| 93 | +- Explorer shows separate last-checked and image-changed times. |
| 94 | +- Stale images are represented as a source freshness state, not as a silent failure. |
| 95 | +- Existing poster image display remains functional. |
| 96 | +- No HLS/video capture is introduced in Phase 1. |
| 97 | + |
| 98 | +## Phase 2 Boundary |
| 99 | + |
| 100 | +Do not start HLS extraction, playlist capture, generated thumbnails, or direct live-video playback as part of Phase 1. |
| 101 | + |
| 102 | +Phase 2 should begin with the lease-based plan in `Storebaelt_On_Demand_Live_Webcam_Enhancement_Plan_2026-06-03.md` after Phase 1 is deployed and observed. That later track should use an explicit client request and TTL renewal model so heavier live capture activates only while a user is viewing the resource. |
| 103 | + |
| 104 | +## Next Concrete Task |
| 105 | + |
| 106 | +Implement Phase 1 as the next code task: |
| 107 | + |
| 108 | +1. Update `publishers/storebaelt_webcams/storebaelt_webcams_publisher.py`. |
| 109 | +2. Update `publishers/storebaelt_webcams/bootstrap_storebaelt_webcams.py`. |
| 110 | +3. Update `tests/test_storebaelt_webcams_publisher.py`. |
| 111 | +4. Update Explorer's deployed-system card freshness display. |
| 112 | +5. Deploy and verify on Oracle and the live Explorer site. |
0 commit comments