Continuous recording model
Recording session
├─ chunk 0 → source segments A, B
├─ chunk 1 → source segments C, D
└─ discontinuity
└─ new recording session → chunk 0
Canonical AI event
├─ active immutable evidence row
└─ superseded immutable boundary row
Recording metadata is created before media upload. The existing idempotency key, byte count,
SHA-256 digest, pre-signed S3 upload, and completion verification contracts are unchanged. Completed
objects remain private in the original/ namespace.
Media ingest and AI analysis are two independent durable workflows joined by segmentId and
analysisRevision:
source segment ─→ recording metadata ─→ S3 media ─→ media completion
│
└────────→ Edge inference queue ─→ zero or more AI events ─→ analysis completion
The media workflow never waits for inference. A two-minute recording can therefore be playable
while four-camera inference is several minutes behind. The final analysis-complete marker is sent
even when a revision found zero events, so an empty result is distinguishable from unfinished work.
Retries remain idempotent in both workflows.
Recording objects carry two explicit provenance fields. recordingOrigin is continuous for
camera capture and manual_upload for an operator-selected file. segmentRole is source_chunk,
review_archive, or manual_original. S3 object metadata mirrors these values for operations, but
the persisted recording metadata is authoritative; clients do not infer product behavior from an
object key or filename.
AI events are stored in DynamoDB and queryable by vessel, camera, and absolute eventAt. Segment
revision counts include every immutable evidence row. Review clients group rows by
canonicalEventId and never count a superseded row as another candidate.
Recording metadata also stores server-owned analysisStatus and analysisCompletedAt. Media
status=completed means the S3 object is ready; analysisStatus=completed means FishTube has
accepted the matching analysis completion marker. These states must not be inferred from one
another.
Human review completion is independent as well. A review archive can have an observer mark, an explicit no-event acknowledgement, or remain unreviewed. The acknowledgement uses a deterministic identifier and is persisted in the existing observer-review DynamoDB table family, so retries do not create duplicate decisions. Report progress is calculated from review archives in minutes while AI evidence remains linked to the underlying source segments.