Skip to content

feat(map-inset): opt-in --map-inset route flags on the drive command - #115

Merged
joepetjr merged 10 commits into
mainfrom
feat/map-inset-flags
Oct 28, 2026
Merged

joepetjr merged 10 commits into
mainfrom
feat/map-inset-flags

Conversation

@joepetjr

Copy link
Copy Markdown
Contributor

What

Opt-in --map-inset off|route on the drive command, plus --map-inset-bundle, --map-inset-trim-start-m, --map-inset-trim-end-m and a repeatable --map-inset-privacy-zone LAT,LON,R. They thread into config.drive.map_inset*, persist in drive state across a resume, and register in the flag registry. Docs in docs/pipeline/01-per-lf-location-labels.md.

Why

#109 landed the render and composite path but left it unreachable. This exposes it as a per-drive choice: a video only gets a map overlay when the operator asks for one. Off (the default) produces the same output as before. route refuses before any encode and lists every missing input (bundle, trim, privacy zone, GPS); it never falls back silently. Photo inserts never block an inset, because stills are spliced in after the burn.

Tests

  • tests/test_regular_lf_map_inset_flags.py (new): config defaults and validation, CLI parsing with sentinel defaults, every option registered with a config mirror, a resume without the flags keeps the saved options, a differing flag beats the saved choice. (The refusal listing is covered by feat(map-inset): render and composite a route inset per regular LF #109's tests/test_regular_lf_map_inset.py.)
  • tests/test_flag_registry.py: new flags registered.
  • 37 related test files (map inset, OST overlay, route claims, CLI, config): 656 passed.
  • ruff check and format clean; tools/check_public_tree.py exits 0.

Move the keycut pin from v0.1.0 to v0.2.0. The day-master cut
(extract_and_concat_segments) now calls keycut's
extract_and_concat_ranges_with_receipt and checks the receipt it returns
with our own load_receipt. If the receipt does not validate, the function
logs an error naming the failing field and returns None, because an
output-to-source time map built from a bad receipt would be wrong. The
signature and return type are unchanged.

keycut 0.1.2 changed the re-encode fallback to seek on the input side
(-ss S -i master -ss 0 -t D). montage_builder.reencode_range_argv mirrors
that argv, so it follows; the lead-seam cut gives the same frames without
decoding from the start of the file. keycut 0.2.0 also probes piece and
output durations for the receipt, so the clean-run command count in the
resume test goes from 4 to 7.

Add a real-ffmpeg test that runs keycut on a synthetic master, loads the
live receipt, maps output time back to source time, and compares the
receipt's keys with the frozen assembly_receipt_v1.json fixture.
# Conflicts:
#	gomoveshift/pipeline/montage_builder.py
#	pyproject.toml
What: when a drive config selects map_inset="route", each regular
long-form video gets a route-only map inset rendered from an offline
bundle and composited inside the existing OST encode. The LF cut now
keeps its keycut receipt beside the concat (opt-in sidecar), the inset
timeline is built from it shifted by the real montage lead, the inset
options and route are folded into the LF OST fingerprint, and the inset
receipt is recorded in drive state.

Refusals happen before the day master is encoded and list every
problem in one error: no bundle or a bundle that fails verification,
either trim not above zero, an unparsable privacy zone, no usable day
GPS trace, or photo/clip inserts on the day. A per-LF renderer refusal
stops the run, naming the LF.

Why: an LF must never silently ship without the map it was asked for,
nor with a partial overlay. With the option off the path is unchanged.
The CLI flags and config fields follow in the next commit; until then
this is unreachable from a real config.
What: adds --map-inset off|route, --map-inset-bundle,
--map-inset-trim-start-m, --map-inset-trim-end-m and a repeatable
--map-inset-privacy-zone, with matching config.drive fields and
validation (bad mode, negative trim, unparsable zone). All five are
registered sentinel flags, so a resume that omits them keeps the first
run's choice and a differing value wins. Documents the flags, refusal
rules and privacy handling and adds a changelog entry.

Why: wires the per-LF inset rendering from the previous commit to the
CLI. Default is off, which leaves the pipeline unchanged.
Stills are spliced into the burned LF, so the map stays on its own frames and the inserted stills carry none.
# Conflicts:
#	gomoveshift/pipeline/day_pipeline.py
@joepetjr joepetjr added the needs-operator Autoland hard-denied this PR; human merge required label Oct 28, 2026
@joepetjr

Copy link
Copy Markdown
Contributor Author

Unclassified (unclassified) and ready to merge -- all checks green.

Offending paths:

  • gomoveshift/cli/handlers/drive.py
  • gomoveshift/cli/parser.py
  • gomoveshift/config.py
  • gomoveshift/pipeline/drive_orchestrator.py
  • gomoveshift/pipeline/drive_state_model.py
  • gomoveshift/pipeline/flag_registry.py

Human merge (all 7 ready hard-denied PRs in Back-Road-Creative/framegrade):
sudo gh-merge-batch Back-Road-Creative/framegrade 54 79 110 111 113 114 115 --wait --yes

This PR alone:
sudo gh-merge-approved 115 --repo Back-Road-Creative/framegrade --wait --yes

@joepetjr
joepetjr merged commit 6a73ce2 into main Oct 28, 2026
10 checks passed
@joepetjr
joepetjr deleted the feat/map-inset-flags branch October 28, 2026 12:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-operator Autoland hard-denied this PR; human merge required

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant