Skip to content

plan

Compute the rename plan and QC report. Read-only.

media-ingest plan [OPTIONS]

plan reads .ingest/manifest.json and computes the exact set of renames, the exclusions, and the warnings, then writes .ingest/plan.json and .ingest/report.html. It is a pure function of the manifest and config: nothing touches the filesystem outside .ingest/. Run it as many times as you like.

Options

  • --root points at a specific project directory. By default, plan finds the project by walking up to the nearest ingest.toml.

Example

media-ingest plan
Planned renames: 1789   excluded: 54   warnings: 9
Mic recordings paired to a camera clip: 58/64
  warning [timezone] dji-action6 on 2026-03-16: camera clock implies UTC-5 but config says UTC-4
  warning [date-range] iphone-export/IMG_0007.mov: capture date 2026-03-13 outside trip range
  ...

Plan:   /Volumes/T7/PROJECTS/2026-03_my-trip/.ingest/plan.json
Report: /Volumes/T7/PROJECTS/2026-03_my-trip/.ingest/report.html

Sample of planned renames:
  DCIM/DJI_20260316184422_0105_D.MP4
    -> media/source/action_cameras/2026-03-16/2026-03-16T184422 - OsmoPocket3 - 0105.mp4
  ...

Review the report, spot-check with 'media-ingest align', then run 'media-ingest apply'.

The naming scheme

Every planned name follows one pattern:

YYYY-MM-DDTHHMMSS - Label - id.ext

The timestamp is the capture time expressed in the single trip timezone (see the timezone model), the label is the device's human name, and the id is a short identifier carried from the original filename. Files land in per-day folders under their group's destination template. Because every name starts with the same timezone-normalized timestamp, sorting by filename gives strict chronological order across every device.

What plan decides

Timezone cross-check

DJI video filenames embed local wall time while their metadata is UTC, so the true UTC offset is recoverable per camera per day from the difference between the two. plan compares that inferred offset against the timezone in ingest.toml and raises a timezone warning for any day where they disagree, for example camera clock implies UTC-5 but config says UTC-4. This is the check that catches a wrong trip timezone before anything moves. See the timezone model.

Exclusions

Files that cannot be confidently placed are excluded, with a stated reason, rather than guessed at:

  • Empty or aborted recordings (smaller than 4 KB, such as the stub WAV a failed take leaves behind).
  • Duplicate content, where two files hash identically. Fast-hash candidates are confirmed with a full-file hash before either is excluded, so near-identical media is never wrongly dropped.
  • Unrecognized devices or types, which also raise a warning.
  • Files with no usable capture timestamp, which also raise a warning.

Excluded files are listed in plan.json and in the report, and are simply left where they are.

Warnings

Beyond timezone mismatches, plan warns about captures outside the configured trip date range, unknown devices, and files with no timestamp. The command prints the first several warnings and points you to the report for the rest. Warnings never block apply; they are review prompts.

Pairing

plan matches DJI Mic recordings to the camera clip they were recorded alongside, by start-time proximity and comparable duration. The summary reports how many mic recordings were paired. Unpaired mic files are normal, for example backup recordings made while the mic was not attached to a camera. It also pairs Osmo audio-backup sidecars to their video by identical filename stem, so the sidecar adopts the video's corrected name and sorts right next to it.

Collisions

If two files would land on the exact same destination name, plan appends numbered suffixes (- 2, - 3, and so on) deterministically and records a collision note. This is common when two identical iPhone models capture on the same second.

Next

Open report.html (see the timeline report), spot-check anything suspicious with align, then run apply.